├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── content └── test.png └── src ├── bin ├── tutorial_01.rs ├── tutorial_02.rs ├── tutorial_03.rs ├── tutorial_04.rs ├── tutorial_05.rs ├── tutorial_06.rs ├── tutorial_07.rs ├── tutorial_08.rs ├── tutorial_09.rs ├── tutorial_10.rs ├── tutorial_11.rs ├── tutorial_12.rs ├── tutorial_13.rs ├── tutorial_14.rs ├── tutorial_15.rs └── tutorial_16.rs ├── camera.rs ├── graphical_math.rs ├── lib.rs └── pipeline.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "ogldev" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "cgmath 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "glium 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", 8 | ] 9 | 10 | [[package]] 11 | name = "android_glue" 12 | version = "0.2.1" 13 | source = "registry+https://github.com/rust-lang/crates.io-index" 14 | 15 | [[package]] 16 | name = "approx" 17 | version = "0.1.1" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | 20 | [[package]] 21 | name = "backtrace" 22 | version = "0.2.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | dependencies = [ 25 | "backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 26 | "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 27 | "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 28 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 29 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 30 | "rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 31 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 32 | ] 33 | 34 | [[package]] 35 | name = "backtrace-sys" 36 | version = "0.1.5" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | dependencies = [ 39 | "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", 40 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 41 | ] 42 | 43 | [[package]] 44 | name = "bitflags" 45 | version = "0.3.3" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | 48 | [[package]] 49 | name = "bitflags" 50 | version = "0.7.0" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | 53 | [[package]] 54 | name = "byteorder" 55 | version = "0.5.3" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | 58 | [[package]] 59 | name = "cfg-if" 60 | version = "0.1.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | 63 | [[package]] 64 | name = "cgl" 65 | version = "0.1.5" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | dependencies = [ 68 | "gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)", 69 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 70 | ] 71 | 72 | [[package]] 73 | name = "cgmath" 74 | version = "0.12.0" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | dependencies = [ 77 | "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 78 | "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 79 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 80 | "rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)", 81 | ] 82 | 83 | [[package]] 84 | name = "cocoa" 85 | version = "0.3.3" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | dependencies = [ 88 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 89 | "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 90 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 91 | "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 92 | ] 93 | 94 | [[package]] 95 | name = "color_quant" 96 | version = "1.0.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | 99 | [[package]] 100 | name = "core-foundation" 101 | version = "0.2.2" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | dependencies = [ 104 | "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 105 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 106 | ] 107 | 108 | [[package]] 109 | name = "core-foundation-sys" 110 | version = "0.2.2" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | dependencies = [ 113 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 114 | ] 115 | 116 | [[package]] 117 | name = "core-graphics" 118 | version = "0.3.2" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | dependencies = [ 121 | "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 122 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 123 | "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", 124 | ] 125 | 126 | [[package]] 127 | name = "crossbeam" 128 | version = "0.2.10" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | 131 | [[package]] 132 | name = "dbghelp-sys" 133 | version = "0.2.0" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | dependencies = [ 136 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 137 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 138 | ] 139 | 140 | [[package]] 141 | name = "deque" 142 | version = "0.3.1" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | dependencies = [ 145 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 146 | ] 147 | 148 | [[package]] 149 | name = "dlib" 150 | version = "0.3.1" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | dependencies = [ 153 | "libloading 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 154 | ] 155 | 156 | [[package]] 157 | name = "dtoa" 158 | version = "0.2.2" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | 161 | [[package]] 162 | name = "dwmapi-sys" 163 | version = "0.1.0" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | dependencies = [ 166 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 167 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 168 | ] 169 | 170 | [[package]] 171 | name = "enum_primitive" 172 | version = "0.1.0" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | dependencies = [ 175 | "num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 176 | ] 177 | 178 | [[package]] 179 | name = "flate2" 180 | version = "0.2.14" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | dependencies = [ 183 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 184 | "miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 185 | ] 186 | 187 | [[package]] 188 | name = "fs2" 189 | version = "0.2.5" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | dependencies = [ 192 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 193 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 194 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 195 | ] 196 | 197 | [[package]] 198 | name = "gcc" 199 | version = "0.3.38" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | 202 | [[package]] 203 | name = "gdi32-sys" 204 | version = "0.1.1" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | dependencies = [ 207 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 208 | ] 209 | 210 | [[package]] 211 | name = "gif" 212 | version = "0.9.0" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | dependencies = [ 215 | "color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 216 | "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 217 | ] 218 | 219 | [[package]] 220 | name = "gl_generator" 221 | version = "0.5.2" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | dependencies = [ 224 | "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 225 | "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 226 | "xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 227 | ] 228 | 229 | [[package]] 230 | name = "gleam" 231 | version = "0.2.24" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | dependencies = [ 234 | "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 235 | "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 236 | ] 237 | 238 | [[package]] 239 | name = "glium" 240 | version = "0.15.0" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | dependencies = [ 243 | "backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 244 | "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 245 | "glutin 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 246 | "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 247 | "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 248 | ] 249 | 250 | [[package]] 251 | name = "glob" 252 | version = "0.2.11" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | 255 | [[package]] 256 | name = "glutin" 257 | version = "0.6.2" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | dependencies = [ 260 | "android_glue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 261 | "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 262 | "cocoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 263 | "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 264 | "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 265 | "dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 266 | "gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 267 | "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 268 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 269 | "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 270 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 271 | "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 272 | "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 273 | "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 274 | "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 275 | "user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 276 | "wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", 277 | "wayland-kbd 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 278 | "wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 279 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 280 | "x11-dl 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 281 | ] 282 | 283 | [[package]] 284 | name = "image" 285 | version = "0.10.4" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | dependencies = [ 288 | "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 289 | "enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 290 | "gif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 291 | "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 292 | "jpeg-decoder 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 293 | "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 294 | "num-rational 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 295 | "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 296 | "png 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 297 | "scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 298 | ] 299 | 300 | [[package]] 301 | name = "inflate" 302 | version = "0.1.1" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | 305 | [[package]] 306 | name = "itoa" 307 | version = "0.1.1" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | 310 | [[package]] 311 | name = "jpeg-decoder" 312 | version = "0.1.9" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | dependencies = [ 315 | "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 316 | "rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 317 | ] 318 | 319 | [[package]] 320 | name = "kernel32-sys" 321 | version = "0.2.2" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | dependencies = [ 324 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 325 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 326 | ] 327 | 328 | [[package]] 329 | name = "khronos_api" 330 | version = "1.0.0" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | 333 | [[package]] 334 | name = "lazy_static" 335 | version = "0.1.16" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | 338 | [[package]] 339 | name = "lazy_static" 340 | version = "0.2.2" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | 343 | [[package]] 344 | name = "libc" 345 | version = "0.2.17" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | 348 | [[package]] 349 | name = "libloading" 350 | version = "0.3.1" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | dependencies = [ 353 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 354 | "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 355 | "target_build_utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 356 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 357 | ] 358 | 359 | [[package]] 360 | name = "log" 361 | version = "0.3.6" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | 364 | [[package]] 365 | name = "lzw" 366 | version = "0.10.0" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | 369 | [[package]] 370 | name = "malloc_buf" 371 | version = "0.0.6" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | dependencies = [ 374 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 375 | ] 376 | 377 | [[package]] 378 | name = "memmap" 379 | version = "0.2.3" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | dependencies = [ 382 | "fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 383 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 384 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 385 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 386 | ] 387 | 388 | [[package]] 389 | name = "miniz-sys" 390 | version = "0.1.7" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | dependencies = [ 393 | "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", 394 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 395 | ] 396 | 397 | [[package]] 398 | name = "num" 399 | version = "0.1.36" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | dependencies = [ 402 | "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 403 | "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 404 | "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 405 | ] 406 | 407 | [[package]] 408 | name = "num-bigint" 409 | version = "0.1.35" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | dependencies = [ 412 | "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 413 | "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 414 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 415 | "rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)", 416 | ] 417 | 418 | [[package]] 419 | name = "num-integer" 420 | version = "0.1.32" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | dependencies = [ 423 | "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 424 | ] 425 | 426 | [[package]] 427 | name = "num-iter" 428 | version = "0.1.32" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | dependencies = [ 431 | "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 432 | "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 433 | ] 434 | 435 | [[package]] 436 | name = "num-rational" 437 | version = "0.1.35" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | dependencies = [ 440 | "num-bigint 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 441 | "num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 442 | "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 443 | "rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)", 444 | ] 445 | 446 | [[package]] 447 | name = "num-traits" 448 | version = "0.1.36" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | 451 | [[package]] 452 | name = "num_cpus" 453 | version = "1.2.0" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | dependencies = [ 456 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 457 | ] 458 | 459 | [[package]] 460 | name = "objc" 461 | version = "0.2.2" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | dependencies = [ 464 | "malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 465 | ] 466 | 467 | [[package]] 468 | name = "osmesa-sys" 469 | version = "0.1.2" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | dependencies = [ 472 | "shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 473 | ] 474 | 475 | [[package]] 476 | name = "phf" 477 | version = "0.7.19" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | dependencies = [ 480 | "phf_shared 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)", 481 | ] 482 | 483 | [[package]] 484 | name = "phf_codegen" 485 | version = "0.7.19" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | dependencies = [ 488 | "phf_generator 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)", 489 | "phf_shared 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)", 490 | ] 491 | 492 | [[package]] 493 | name = "phf_generator" 494 | version = "0.7.19" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | dependencies = [ 497 | "phf_shared 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)", 498 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 499 | ] 500 | 501 | [[package]] 502 | name = "phf_shared" 503 | version = "0.7.19" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | 506 | [[package]] 507 | name = "pkg-config" 508 | version = "0.3.8" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | 511 | [[package]] 512 | name = "png" 513 | version = "0.5.2" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | dependencies = [ 516 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 517 | "flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", 518 | "inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 519 | "num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 520 | ] 521 | 522 | [[package]] 523 | name = "rand" 524 | version = "0.3.14" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | dependencies = [ 527 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 528 | ] 529 | 530 | [[package]] 531 | name = "rayon" 532 | version = "0.5.0" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | dependencies = [ 535 | "deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 536 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 537 | "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 538 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 539 | ] 540 | 541 | [[package]] 542 | name = "rustc-demangle" 543 | version = "0.1.3" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | 546 | [[package]] 547 | name = "rustc-serialize" 548 | version = "0.3.21" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | 551 | [[package]] 552 | name = "rustc_version" 553 | version = "0.1.7" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | dependencies = [ 556 | "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", 557 | ] 558 | 559 | [[package]] 560 | name = "scoped_threadpool" 561 | version = "0.1.7" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | 564 | [[package]] 565 | name = "semver" 566 | version = "0.1.20" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | 569 | [[package]] 570 | name = "serde" 571 | version = "0.7.15" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | 574 | [[package]] 575 | name = "serde" 576 | version = "0.8.17" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | 579 | [[package]] 580 | name = "serde_json" 581 | version = "0.8.3" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | dependencies = [ 584 | "dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 585 | "itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 586 | "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 587 | "serde 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)", 588 | ] 589 | 590 | [[package]] 591 | name = "shared_library" 592 | version = "0.1.5" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | dependencies = [ 595 | "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 596 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 597 | ] 598 | 599 | [[package]] 600 | name = "shell32-sys" 601 | version = "0.1.1" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | dependencies = [ 604 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 605 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 606 | ] 607 | 608 | [[package]] 609 | name = "smallvec" 610 | version = "0.1.8" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | 613 | [[package]] 614 | name = "target_build_utils" 615 | version = "0.1.2" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | dependencies = [ 618 | "phf 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)", 619 | "phf_codegen 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)", 620 | "serde_json 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", 621 | ] 622 | 623 | [[package]] 624 | name = "tempfile" 625 | version = "2.1.4" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | dependencies = [ 628 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 629 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 630 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 631 | "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 632 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 633 | ] 634 | 635 | [[package]] 636 | name = "user32-sys" 637 | version = "0.1.2" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | dependencies = [ 640 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 641 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 642 | ] 643 | 644 | [[package]] 645 | name = "wayland-client" 646 | version = "0.5.12" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | dependencies = [ 649 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 650 | "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 651 | "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 652 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 653 | "wayland-scanner 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", 654 | "wayland-sys 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", 655 | ] 656 | 657 | [[package]] 658 | name = "wayland-kbd" 659 | version = "0.3.6" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | dependencies = [ 662 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 663 | "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 664 | "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 665 | "memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 666 | "wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", 667 | ] 668 | 669 | [[package]] 670 | name = "wayland-scanner" 671 | version = "0.5.11" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | dependencies = [ 674 | "xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 675 | ] 676 | 677 | [[package]] 678 | name = "wayland-sys" 679 | version = "0.5.11" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | dependencies = [ 682 | "dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 683 | "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 684 | ] 685 | 686 | [[package]] 687 | name = "wayland-window" 688 | version = "0.2.3" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | dependencies = [ 691 | "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 692 | "tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 693 | "wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", 694 | ] 695 | 696 | [[package]] 697 | name = "winapi" 698 | version = "0.2.8" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | 701 | [[package]] 702 | name = "winapi-build" 703 | version = "0.1.1" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | 706 | [[package]] 707 | name = "x11-dl" 708 | version = "2.11.0" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | dependencies = [ 711 | "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 712 | "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 713 | "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 714 | ] 715 | 716 | [[package]] 717 | name = "xml-rs" 718 | version = "0.3.4" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | dependencies = [ 721 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 722 | ] 723 | 724 | [metadata] 725 | "checksum android_glue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e2b80445d331077679dfc6f3014f3e9ab7083e588423d35041d3fc017198189" 726 | "checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94" 727 | "checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" 728 | "checksum backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3602e8d8c43336088a8505fa55cae2b3884a9be29440863a11528a42f46f6bb7" 729 | "checksum bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32866f4d103c4e438b1db1158aa1b1a80ee078e5d77a59a2f906fd62a577389c" 730 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" 731 | "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" 732 | "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" 733 | "checksum cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8bdd78cca65a739cb5475dbf6b6bbb49373e327f4a6f2b499c0f98632df38c10" 734 | "checksum cgmath 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "232472604dbad61c384edfc4d833315d487894826856836b7227b37fe3abe02b" 735 | "checksum cocoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3afe4613f57a171039a98db1773f5840b5743cf85aaf03afb65ddfade4f4a9db" 736 | "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d" 737 | "checksum core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "20a6d0448d3a99d977ae4a2aa5a98d886a923e863e81ad9ff814645b6feb3bbd" 738 | "checksum core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05eed248dc504a5391c63794fe4fb64f46f071280afaa1b73308f3c0ce4574c5" 739 | "checksum core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0c56c6022ba22aedbaa7d231be545778becbe1c7aceda4c82ba2f2084dd4c723" 740 | "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" 741 | "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" 742 | "checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf" 743 | "checksum dlib 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "148bce4ce1c36c4509f29cb54e62c2bd265551a9b00b38070fad551a851866ec" 744 | "checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d" 745 | "checksum dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07c4c7cc7b396419bc0a4d90371d0cee16cb5053b53647d287c0b728000c41fe" 746 | "checksum enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f79eff5be92a4d7d5bddf7daa7d650717ea71628634efe6ca7bcda85b2183c23" 747 | "checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb" 748 | "checksum fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bcd414e5a1a979b931bb92f41b7a54106d3f6d2e6c253e9ce943b7cd468251ef" 749 | "checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5" 750 | "checksum gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "65256ec4dc2592e6f05bfc1ca3b956a4e0698aa90b1dff1f5687d55a5a3fd59a" 751 | "checksum gif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01c7c19a035de94bd7afbaa62c241aadfbdf1a70f560b348d2312eafa566ca16" 752 | "checksum gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1d8edc81c5ae84605a62f5dac661a2313003b26d59839f81d47d46cf0f16a55" 753 | "checksum gleam 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b04d6c8a1df841e48dfe99ed67829c9d1d17b1bb3e44c5f3283992010e20359b" 754 | "checksum glium 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30bfe6ac8600d25f7f2a1e3203566b156d66e7c2f358f6bb79b5419ddaecd671" 755 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 756 | "checksum glutin 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06786fae66e7aa8464b3d8d3fb7a7c470f89d62ae511f9613ea7fbbeef61d680" 757 | "checksum image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "76df2dce95fef56fd35dbc41c36e37b19aede703c6be7739e8b65d5788ffc728" 758 | "checksum inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" 759 | "checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1" 760 | "checksum jpeg-decoder 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d726303fa914eb8ee6f25b414f0a592ae9e2b7e0c169caea952dc6f30f076df6" 761 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 762 | "checksum khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09c9d3760673c427d46f91a0350f0a84a52e6bc5a84adf26dc610b6c52436630" 763 | "checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" 764 | "checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b" 765 | "checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8" 766 | "checksum libloading 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "84816a8c6ed8163dfe0dbdd2b09d35c6723270ea77a4c7afa4bedf038a36cb99" 767 | "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054" 768 | "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" 769 | "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 770 | "checksum memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f20f72ed93291a72e22e8b16bb18762183bb4943f0f483da5b8be1a9e8192752" 771 | "checksum miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d1f4d337a01c32e1f2122510fed46393d53ca35a7f429cb0450abaedfa3ed54" 772 | "checksum num 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "bde7c03b09e7c6a301ee81f6ddf66d7a28ec305699e3d3b056d2fc56470e3120" 773 | "checksum num-bigint 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "88b14378471f7c2adc5262f05b4701ef53e8da376453a8d8fee48e51db745e49" 774 | "checksum num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "fb24d9bfb3f222010df27995441ded1e954f8f69cd35021f6bef02ca9552fb92" 775 | "checksum num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c" 776 | "checksum num-rational 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "54ff603b8334a72fbb27fe66948aac0abaaa40231b3cecd189e76162f6f38aaf" 777 | "checksum num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c" 778 | "checksum num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "55aabf4e2d6271a2e4e4c0f2ea1f5b07cc589cc1a9e9213013b54a76678ca4f3" 779 | "checksum objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "877f30f37acef6749b1841cceab289707f211aecfc756553cd63976190e6cc2e" 780 | "checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" 781 | "checksum phf 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "95cb41511b13e592110b5c8323c1d489513b6db919148f909b8b804be73a74b5" 782 | "checksum phf_codegen 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8b74506ea0ea5f6adbef815c1e964daa2d395e7c29b7196d390a67a31fa2a020" 783 | "checksum phf_generator 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d5e1d4b224dfc609b025ea389e6eb9b850ae5814272880d7d75d71acc3d57c88" 784 | "checksum phf_shared 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "9f3d84458c4040eb4b9e626cb551a2dc46d92ea96b1c30331aa9fce9abd2c438" 785 | "checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa" 786 | "checksum png 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06208e2ee243e3118a55dda9318f821f206d8563fb8d4df258767f8e62bb0997" 787 | "checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5" 788 | "checksum rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b6a6e05e0e6b703e9f2ad266eb63f3712e693a17a2702b95a23de14ce8defa9" 789 | "checksum rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1430d286cadb237c17c885e25447c982c97113926bb579f4379c0eca8d9586dc" 790 | "checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818" 791 | "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" 792 | "checksum scoped_threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3ef399c8893e8cb7aa9696e895427fab3a6bf265977bb96e126f24ddd2cda85a" 793 | "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" 794 | "checksum serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0e0732aa8ec4267f61815a396a942ba3525062e3bd5520aa8419927cfc0a92" 795 | "checksum serde 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "784e249221c84265caeb1e2fe48aeada86f67f5acb151bd3903c4585969e43f6" 796 | "checksum serde_json 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1cb6b19e74d9f65b9d03343730b643d729a446b29376785cd65efdff4675e2fc" 797 | "checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a" 798 | "checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d" 799 | "checksum smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fcc8d19212aacecf95e4a7a2179b26f7aeb9732a915cf01f05b0d3e044865410" 800 | "checksum target_build_utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54c550e226618cd35334b75e92bfa5437c61474bdb75c38bf330ab5a8037b77c" 801 | "checksum tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9270837a93bad1b1dac18fe67e786b3c960513af86231f6f4f57fddd594ff0c8" 802 | "checksum user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6717129de5ac253f5642fc78a51d0c7de6f9f53d617fc94e9bae7f6e71cf5504" 803 | "checksum wayland-client 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ced3094c157b5cc0a08d40530e1a627d9f88b9a436971338d2646439128a559e" 804 | "checksum wayland-kbd 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "73bc10e84c1da90777beffecd24742baea17564ffc2a9918af41871c748eb050" 805 | "checksum wayland-scanner 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5a1869370d6bafcbabae8724511d803f4e209a70e94ad94a4249269534364f66" 806 | "checksum wayland-sys 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9633f7fe5de56544215f82eaf1b76bf1b584becf7f08b58cbef4c2c7d10e803a" 807 | "checksum wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "309b69d3a863c9c21422d889fb7d98cf02f8a2ca054960a49243ce5b67ad884c" 808 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 809 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 810 | "checksum x11-dl 2.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4c7f0a7fb861a1bde4aa23bbda9509bda6b87de4d47c322f86e4c88241ebdd" 811 | "checksum xml-rs 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65e74b96bd3179209dc70a980da6df843dff09e46eee103a0376c0949257e3ef" 812 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ogldev" 3 | version = "0.1.0" 4 | authors = ["SLMT"] 5 | 6 | [dependencies] 7 | glium = "0.15.0" 8 | cgmath = "0.12.0" 9 | image = "*" 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OGLdev Tutorials in Rust 2 | 3 | [OGLdev](http://ogldev.atspace.co.uk/) is a very nice serise of tutorials that introduces basic knowledge for writing a OpenGL program. The original tutorials are written in C. However, I want to reproduce the same results in [Rust](https://www.rust-lang.org/) for fun and learning. So that is why I created this repository. 4 | 5 | I used [glium](https://github.com/tomaka/glium) to use OpenGL in Rust. It is quite different from the one used by the original tutorials. You may see lots of difference (including variable names, function calls... etc.) between those tutorials and my implementations. Just stay calm. Take some time to read carefully. You will find that they are basically the same. At least they try to archive the same goals. 6 | 7 | The [documents](http://tomaka.github.io/glium/glium/index.html) of glium will be very useful when you dig my code. 8 | 9 | ## The Goal of Each Tutorial 10 | 11 | The titles below summarize the goals of the tutorials on [OGLdev](http://ogldev.atspace.co.uk/). Each of them links to a Rust implementation of the corresponding tutorial. 12 | 13 | 1. [To Create A Window](src/bin/tutorial_01.rs) 14 | 2. [To Draw A Dot](src/bin/tutorial_02.rs) 15 | 3. [To Draw A Triangle](src/bin/tutorial_03.rs) 16 | 4. [To Use Shader Programs](src/bin/tutorial_04.rs) 17 | - This one does not have too much difference from the 2nd and 3rd tutorial since I have used shader programs in those tutorials. 18 | 5. [To Use Uniform Variables](src/bin/tutorial_05.rs) 19 | 6. [To Perform Translation Transformation](src/bin/tutorial_06.rs) 20 | 7. [To Perform Rotation Transformation](src/bin/tutorial_07.rs) 21 | 8. [To Perform Scaling Transformation](src/bin/tutorial_08.rs) 22 | 9. [To Interpolate Color inside a Triangle](src/bin/tutorial_09.rs) 23 | 10. [To Draw with A Index Buffer](src/bin/tutorial_10.rs) 24 | 11. [To Concatenate Transformations](src/bin/tutorial_11.rs) 25 | 12. [To Perform Perspective Projection](src/bin/tutorial_12.rs) 26 | 13. [To Perform View Transformation](src/bin/tutorial_13.rs) 27 | 14. [To Move The Camera Using Arrow Keys On The Keyboard](src/bin/tutorial_14.rs) 28 | 15. [To Move The Camera Using Both The Keyboard And The Mouse](src/bin/tutorial_15.rs) 29 | 16. [To Draw with Textures](src/bin/tutorial_16.rs) 30 | - There is lots of difference between this one and the original tutorial, because `glium` does many great jobs in Rust and we just need to add a few code to make the same effect. 31 | 32 | ## How to Run It ? 33 | 34 | This command should build the whole project and run the `n`-th tutorial: 35 | 36 | ``` 37 | > cargo run --bin tutorial_n 38 | ``` 39 | 40 | For example, to run the first tutorial: 41 | 42 | ``` 43 | > cargo run --bin tutorial_01 44 | ``` 45 | -------------------------------------------------------------------------------- /content/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SLMT/rust-ogldev/014e9a1c9260a898d44ea36a11f62c0a92b126b2/content/test.png -------------------------------------------------------------------------------- /src/bin/tutorial_01.rs: -------------------------------------------------------------------------------- 1 | extern crate glium; 2 | 3 | use glium::{DisplayBuild, Surface}; 4 | use glium::glutin::{Event, WindowBuilder}; 5 | 6 | fn main() { 7 | // Set up and create a window 8 | let display = WindowBuilder::new() 9 | .with_dimensions(1024, 768) 10 | .with_srgb(Some(true)) 11 | .with_title("Tutorial 01") 12 | .build_glium() 13 | .unwrap(); 14 | 15 | loop { 16 | // Draw the background 17 | let mut frame = display.draw(); 18 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 19 | frame.finish().unwrap(); 20 | 21 | // Handle events 22 | for event in display.poll_events() { 23 | match event { 24 | Event::Closed => return, 25 | _ => () 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/bin/tutorial_02.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | 4 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 5 | use glium::glutin::{Event, WindowBuilder}; 6 | use glium::index::{NoIndices, PrimitiveType}; 7 | use glium::uniforms::EmptyUniforms; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | 10 | // Represent a 3D vertex 11 | #[derive(Copy, Clone)] 12 | struct Vertex { 13 | position: [f32; 3] 14 | } 15 | 16 | // Let glium implement Vertex for us 17 | implement_vertex!(Vertex, position); 18 | 19 | // Some constants can be re-used 20 | const EMPTY_UNIFORMS: EmptyUniforms = EmptyUniforms; 21 | 22 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 23 | let vertex = Vertex { position: [0.0, 0.0, 0.0] }; 24 | let point = vec![vertex]; 25 | let vertex_buffer = VertexBuffer::new(display, &point).unwrap(); 26 | vertex_buffer 27 | } 28 | 29 | fn create_shaders(display: &GlutinFacade) -> Program { 30 | let vertex_shader_src = r#" 31 | #version 140 32 | in vec3 position; 33 | void main() { 34 | gl_Position = vec4(position, 1.0); 35 | } 36 | "#; 37 | 38 | let fragment_shader_src = r#" 39 | #version 140 40 | out vec4 color; 41 | void main() { 42 | color = vec4(1.0, 0.0, 0.0, 1.0); 43 | } 44 | "#; 45 | 46 | Program::from_source(display, 47 | vertex_shader_src, fragment_shader_src, None).unwrap() 48 | } 49 | 50 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, program: &Program) { 51 | let mut frame = display.draw(); 52 | 53 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 54 | 55 | frame.draw(vertex_buffer, &NoIndices(PrimitiveType::Points), program, 56 | &EMPTY_UNIFORMS, &Default::default()).unwrap(); 57 | 58 | frame.finish().unwrap(); 59 | } 60 | 61 | fn main() { 62 | // Set up and create a window 63 | let display = WindowBuilder::new() 64 | .with_dimensions(1024, 768) 65 | .with_srgb(Some(true)) 66 | .with_title("Tutorial 02") 67 | .build_glium() 68 | .unwrap(); 69 | 70 | // Create a vertex buffer 71 | let vertex_buffer = create_vertex_buffer(&display); 72 | 73 | // Create a shader program 74 | let program = create_shaders(&display); 75 | 76 | // Main loop 77 | loop { 78 | // Render 79 | render_scene(&display, &vertex_buffer, &program); 80 | 81 | // Handle events 82 | for event in display.poll_events() { 83 | match event { 84 | Event::Closed => return, 85 | _ => () 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/bin/tutorial_03.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | 4 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 5 | use glium::glutin::{Event, WindowBuilder}; 6 | use glium::index::{NoIndices, PrimitiveType}; 7 | use glium::uniforms::EmptyUniforms; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | 10 | // Represent a 3D vertex 11 | #[derive(Copy, Clone)] 12 | struct Vertex { 13 | position: [f32; 3] 14 | } 15 | 16 | // Let glium implement Vertex for us 17 | implement_vertex!(Vertex, position); 18 | 19 | // Some constants can be re-used 20 | const EMPTY_UNIFORMS: EmptyUniforms = EmptyUniforms; 21 | 22 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 23 | let vertices = vec![ 24 | Vertex { position: [-1.0, -1.0, 0.0] }, 25 | Vertex { position: [1.0, -1.0, 0.0] }, 26 | Vertex { position: [0.0, 1.0, 0.0] } 27 | ]; 28 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 29 | vertex_buffer 30 | } 31 | 32 | fn create_shaders(display: &GlutinFacade) -> Program { 33 | let vertex_shader_src = r#" 34 | #version 140 35 | in vec3 position; 36 | void main() { 37 | gl_Position = vec4(position, 1.0); 38 | } 39 | "#; 40 | 41 | let fragment_shader_src = r#" 42 | #version 140 43 | out vec4 color; 44 | void main() { 45 | color = vec4(1.0, 0.0, 0.0, 1.0); 46 | } 47 | "#; 48 | 49 | Program::from_source(display, 50 | vertex_shader_src, fragment_shader_src, None).unwrap() 51 | } 52 | 53 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, program: &Program) { 54 | let mut frame = display.draw(); 55 | 56 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 57 | 58 | frame.draw(vertex_buffer, &NoIndices(PrimitiveType::TrianglesList), program, 59 | &EMPTY_UNIFORMS, &Default::default()).unwrap(); 60 | 61 | frame.finish().unwrap(); 62 | } 63 | 64 | fn main() { 65 | // Set up and create a window 66 | let display = WindowBuilder::new() 67 | .with_dimensions(1024, 768) 68 | .with_srgb(Some(true)) 69 | .with_title("Tutorial 03") 70 | .build_glium() 71 | .unwrap(); 72 | 73 | // Create a vertex buffer 74 | let vertex_buffer = create_vertex_buffer(&display); 75 | 76 | // Create a shader program 77 | let program = create_shaders(&display); 78 | 79 | // Main loop 80 | loop { 81 | // Render 82 | render_scene(&display, &vertex_buffer, &program); 83 | 84 | // Handle events 85 | for event in display.poll_events() { 86 | match event { 87 | Event::Closed => return, 88 | _ => () 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/bin/tutorial_04.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | 4 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 5 | use glium::glutin::{Event, WindowBuilder}; 6 | use glium::index::{NoIndices, PrimitiveType}; 7 | use glium::uniforms::EmptyUniforms; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | 10 | // Represent a 3D vertex 11 | #[derive(Copy, Clone)] 12 | struct Vertex { 13 | position: [f32; 3] 14 | } 15 | 16 | // Let glium implement Vertex for us 17 | implement_vertex!(Vertex, position); 18 | 19 | // Some constants can be re-used 20 | const EMPTY_UNIFORMS: EmptyUniforms = EmptyUniforms; 21 | 22 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 23 | let vertices = vec![ 24 | Vertex { position: [-1.0, -1.0, 0.0] }, 25 | Vertex { position: [1.0, -1.0, 0.0] }, 26 | Vertex { position: [0.0, 1.0, 0.0] } 27 | ]; 28 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 29 | vertex_buffer 30 | } 31 | 32 | fn create_shaders(display: &GlutinFacade) -> Program { 33 | let vertex_shader_src = r#" 34 | #version 330 35 | 36 | layout (location = 0) in vec3 position; 37 | 38 | void main() { 39 | gl_Position = vec4(0.5 * position.x, 0.5 * position.y, position.z, 1.0); 40 | } 41 | "#; 42 | 43 | let fragment_shader_src = r#" 44 | #version 330 45 | 46 | out vec4 color; 47 | 48 | void main() { 49 | color = vec4(1.0, 0.0, 0.0, 1.0); 50 | } 51 | "#; 52 | 53 | Program::from_source(display, 54 | vertex_shader_src, fragment_shader_src, None).unwrap() 55 | } 56 | 57 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, program: &Program) { 58 | let mut frame = display.draw(); 59 | 60 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 61 | 62 | frame.draw(vertex_buffer, &NoIndices(PrimitiveType::TrianglesList), program, 63 | &EMPTY_UNIFORMS, &Default::default()).unwrap(); 64 | 65 | frame.finish().unwrap(); 66 | } 67 | 68 | fn main() { 69 | // Set up and create a window 70 | let display = WindowBuilder::new() 71 | .with_dimensions(1024, 768) 72 | .with_srgb(Some(true)) 73 | .with_title("Tutorial 04") 74 | .build_glium() 75 | .unwrap(); 76 | 77 | // Create a vertex buffer 78 | let vertex_buffer = create_vertex_buffer(&display); 79 | 80 | // Create a shader program 81 | let program = create_shaders(&display); 82 | 83 | // Main loop 84 | loop { 85 | // Render 86 | render_scene(&display, &vertex_buffer, &program); 87 | 88 | // Handle events 89 | for event in display.poll_events() { 90 | match event { 91 | Event::Closed => return, 92 | _ => () 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/bin/tutorial_05.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | 4 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 5 | use glium::glutin::{Event, WindowBuilder}; 6 | use glium::index::{NoIndices, PrimitiveType}; 7 | use glium::backend::glutin_backend::GlutinFacade; 8 | 9 | // Represent a 3D vertex 10 | #[derive(Copy, Clone)] 11 | struct Vertex { 12 | position: [f32; 3] 13 | } 14 | 15 | // Let glium implement Vertex for us 16 | implement_vertex!(Vertex, position); 17 | 18 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 19 | let vertices = vec![ 20 | Vertex { position: [-1.0, -1.0, 0.0] }, 21 | Vertex { position: [1.0, -1.0, 0.0] }, 22 | Vertex { position: [0.0, 1.0, 0.0] } 23 | ]; 24 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 25 | vertex_buffer 26 | } 27 | 28 | fn create_shaders(display: &GlutinFacade) -> Program { 29 | let vertex_shader_src = r#" 30 | #version 330 31 | 32 | layout (location = 0) in vec3 position; 33 | 34 | uniform float gScale; 35 | 36 | void main() { 37 | gl_Position = vec4(gScale * position.x, gScale * position.y, position.z, 1.0); 38 | } 39 | "#; 40 | 41 | let fragment_shader_src = r#" 42 | #version 330 43 | 44 | out vec4 color; 45 | 46 | void main() { 47 | color = vec4(1.0, 0.0, 0.0, 1.0); 48 | } 49 | "#; 50 | 51 | Program::from_source(display, 52 | vertex_shader_src, fragment_shader_src, None).unwrap() 53 | } 54 | 55 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, program: &Program, 56 | scale: f32) { 57 | 58 | let uniform = uniform!{ gScale: scale.sin() }; 59 | 60 | let mut frame = display.draw(); 61 | 62 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 63 | 64 | frame.draw(vertex_buffer, &NoIndices(PrimitiveType::TrianglesList), program, 65 | &uniform, &Default::default()).unwrap(); 66 | 67 | frame.finish().unwrap(); 68 | } 69 | 70 | fn main() { 71 | // Set up and create a window 72 | let display = WindowBuilder::new() 73 | .with_dimensions(1024, 768) 74 | .with_srgb(Some(true)) 75 | .with_title("Tutorial 05") 76 | .build_glium() 77 | .unwrap(); 78 | 79 | // Create a vertex buffer 80 | let vertex_buffer = create_vertex_buffer(&display); 81 | 82 | // Create a shader program 83 | let program = create_shaders(&display); 84 | 85 | // Main loop 86 | let mut scale: f32 = 0.0; 87 | loop { 88 | // Change the scale 89 | // (I use a smaller factor than the one used in the original source code 90 | // since the original factor is too large in my case) 91 | scale += 0.0001; 92 | 93 | // Render 94 | render_scene(&display, &vertex_buffer, &program, scale); 95 | 96 | // Handle events 97 | for event in display.poll_events() { 98 | match event { 99 | Event::Closed => return, 100 | _ => () 101 | } 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/bin/tutorial_06.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate cgmath; 4 | 5 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 6 | use glium::glutin::{Event, WindowBuilder}; 7 | use glium::index::{NoIndices, PrimitiveType}; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | use cgmath::{Matrix, Matrix4}; 10 | 11 | // Represent a 3D vertex 12 | #[derive(Copy, Clone)] 13 | struct Vertex { 14 | position: [f32; 3] 15 | } 16 | 17 | // Let glium implement Vertex for us 18 | implement_vertex!(Vertex, position); 19 | 20 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 21 | let vertices = vec![ 22 | Vertex { position: [-1.0, -1.0, 0.0] }, 23 | Vertex { position: [1.0, -1.0, 0.0] }, 24 | Vertex { position: [0.0, 1.0, 0.0] } 25 | ]; 26 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 27 | vertex_buffer 28 | } 29 | 30 | fn create_shaders(display: &GlutinFacade) -> Program { 31 | let vertex_shader_src = r#" 32 | #version 330 33 | 34 | layout (location = 0) in vec3 position; 35 | 36 | uniform mat4 gWorld; 37 | 38 | void main() { 39 | gl_Position = gWorld * vec4(position, 1.0); 40 | } 41 | "#; 42 | 43 | let fragment_shader_src = r#" 44 | #version 330 45 | 46 | out vec4 color; 47 | 48 | void main() { 49 | color = vec4(1.0, 0.0, 0.0, 1.0); 50 | } 51 | "#; 52 | 53 | Program::from_source(display, 54 | vertex_shader_src, fragment_shader_src, None).unwrap() 55 | } 56 | 57 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, program: &Program, 58 | scale: f32) { 59 | 60 | // Build the transform matrix 61 | // Note that the matrix is in column-major order 62 | // so you need to transpose it for OpenGL 63 | let world: [[f32; 4]; 4] = Matrix4::new( 64 | 1.0, 0.0, 0.0, scale.sin(), 65 | 0.0, 1.0, 0.0, 0.0, 66 | 0.0, 0.0, 1.0, 0.0, 67 | 0.0, 0.0, 0.0, 1.0 68 | ).transpose().into(); 69 | 70 | let uniform = uniform!{ gWorld: world }; 71 | 72 | let mut frame = display.draw(); 73 | 74 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 75 | 76 | frame.draw(vertex_buffer, &NoIndices(PrimitiveType::TrianglesList), program, 77 | &uniform, &Default::default()).unwrap(); 78 | 79 | frame.finish().unwrap(); 80 | } 81 | 82 | fn main() { 83 | // Set up and create a window 84 | let display = WindowBuilder::new() 85 | .with_dimensions(1024, 768) 86 | .with_srgb(Some(true)) 87 | .with_title("Tutorial 06") 88 | .build_glium() 89 | .unwrap(); 90 | 91 | // Create a vertex buffer 92 | let vertex_buffer = create_vertex_buffer(&display); 93 | 94 | // Create a shader program 95 | let program = create_shaders(&display); 96 | 97 | // Main loop 98 | let mut scale: f32 = 0.0; 99 | loop { 100 | // Change the scale 101 | // (I use a smaller factor than the one used in the original source code 102 | // since the original factor is too large in my case) 103 | scale += 0.0001; 104 | 105 | // Render 106 | render_scene(&display, &vertex_buffer, &program, scale); 107 | 108 | // Handle events 109 | for event in display.poll_events() { 110 | match event { 111 | Event::Closed => return, 112 | _ => () 113 | } 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/bin/tutorial_07.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate cgmath; 4 | 5 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 6 | use glium::glutin::{Event, WindowBuilder}; 7 | use glium::index::{NoIndices, PrimitiveType}; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | use cgmath::{Matrix, Matrix4}; 10 | 11 | // Represent a 3D vertex 12 | #[derive(Copy, Clone)] 13 | struct Vertex { 14 | position: [f32; 3] 15 | } 16 | 17 | // Let glium implement Vertex for us 18 | implement_vertex!(Vertex, position); 19 | 20 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 21 | let vertices = vec![ 22 | Vertex { position: [-1.0, -1.0, 0.0] }, 23 | Vertex { position: [1.0, -1.0, 0.0] }, 24 | Vertex { position: [0.0, 1.0, 0.0] } 25 | ]; 26 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 27 | vertex_buffer 28 | } 29 | 30 | fn create_shaders(display: &GlutinFacade) -> Program { 31 | let vertex_shader_src = r#" 32 | #version 330 33 | 34 | layout (location = 0) in vec3 position; 35 | 36 | uniform mat4 gWorld; 37 | 38 | void main() { 39 | gl_Position = gWorld * vec4(position, 1.0); 40 | } 41 | "#; 42 | 43 | let fragment_shader_src = r#" 44 | #version 330 45 | 46 | out vec4 color; 47 | 48 | void main() { 49 | color = vec4(1.0, 0.0, 0.0, 1.0); 50 | } 51 | "#; 52 | 53 | Program::from_source(display, 54 | vertex_shader_src, fragment_shader_src, None).unwrap() 55 | } 56 | 57 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, program: &Program, 58 | scale: f32) { 59 | 60 | // Build the transform matrix 61 | // Note that the matrix is in column-major order 62 | // so you need to transpose it for OpenGL 63 | let sin_scale = scale.sin(); 64 | let cos_scale = scale.cos(); 65 | let world: [[f32; 4]; 4] = Matrix4::new( 66 | cos_scale, -sin_scale, 0.0, 0.0, 67 | sin_scale, cos_scale, 0.0, 0.0, 68 | 0.0, 0.0, 1.0, 0.0, 69 | 0.0, 0.0, 0.0, 1.0 70 | ).transpose().into(); 71 | 72 | let uniform = uniform!{ gWorld: world }; 73 | 74 | let mut frame = display.draw(); 75 | 76 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 77 | 78 | frame.draw(vertex_buffer, &NoIndices(PrimitiveType::TrianglesList), program, 79 | &uniform, &Default::default()).unwrap(); 80 | 81 | frame.finish().unwrap(); 82 | } 83 | 84 | fn main() { 85 | // Set up and create a window 86 | let display = WindowBuilder::new() 87 | .with_dimensions(1024, 768) 88 | .with_srgb(Some(true)) 89 | .with_title("Tutorial 07") 90 | .build_glium() 91 | .unwrap(); 92 | 93 | // Create a vertex buffer 94 | let vertex_buffer = create_vertex_buffer(&display); 95 | 96 | // Create a shader program 97 | let program = create_shaders(&display); 98 | 99 | // Main loop 100 | let mut scale: f32 = 0.0; 101 | loop { 102 | // Change the scale 103 | // (I use a smaller factor than the one used in the original source code 104 | // since the original factor is too large in my case) 105 | scale += 0.0001; 106 | 107 | // Render 108 | render_scene(&display, &vertex_buffer, &program, scale); 109 | 110 | // Handle events 111 | for event in display.poll_events() { 112 | match event { 113 | Event::Closed => return, 114 | _ => () 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/bin/tutorial_08.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate cgmath; 4 | 5 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 6 | use glium::glutin::{Event, WindowBuilder}; 7 | use glium::index::{NoIndices, PrimitiveType}; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | use cgmath::{Matrix, Matrix4}; 10 | 11 | // Represent a 3D vertex 12 | #[derive(Copy, Clone)] 13 | struct Vertex { 14 | position: [f32; 3] 15 | } 16 | 17 | // Let glium implement Vertex for us 18 | implement_vertex!(Vertex, position); 19 | 20 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 21 | let vertices = vec![ 22 | Vertex { position: [-1.0, -1.0, 0.0] }, 23 | Vertex { position: [1.0, -1.0, 0.0] }, 24 | Vertex { position: [0.0, 1.0, 0.0] } 25 | ]; 26 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 27 | vertex_buffer 28 | } 29 | 30 | fn create_shaders(display: &GlutinFacade) -> Program { 31 | let vertex_shader_src = r#" 32 | #version 330 33 | 34 | layout (location = 0) in vec3 position; 35 | 36 | uniform mat4 gWorld; 37 | 38 | void main() { 39 | gl_Position = gWorld * vec4(position, 1.0); 40 | } 41 | "#; 42 | 43 | let fragment_shader_src = r#" 44 | #version 330 45 | 46 | out vec4 color; 47 | 48 | void main() { 49 | color = vec4(1.0, 0.0, 0.0, 1.0); 50 | } 51 | "#; 52 | 53 | Program::from_source(display, 54 | vertex_shader_src, fragment_shader_src, None).unwrap() 55 | } 56 | 57 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, program: &Program, 58 | scale: f32) { 59 | 60 | // Build the transform matrix 61 | // Note that the matrix is in column-major order 62 | // so you need to transpose it for OpenGL 63 | let sin_scale = scale.sin(); 64 | let world: [[f32; 4]; 4] = Matrix4::new( 65 | sin_scale, 0.0, 0.0, 0.0, 66 | 0.0, sin_scale, 0.0, 0.0, 67 | 0.0, 0.0, sin_scale, 0.0, 68 | 0.0, 0.0, 0.0, 1.0 69 | ).transpose().into(); 70 | 71 | let uniform = uniform!{ gWorld: world }; 72 | 73 | let mut frame = display.draw(); 74 | 75 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 76 | 77 | frame.draw(vertex_buffer, &NoIndices(PrimitiveType::TrianglesList), program, 78 | &uniform, &Default::default()).unwrap(); 79 | 80 | frame.finish().unwrap(); 81 | } 82 | 83 | fn main() { 84 | // Set up and create a window 85 | let display = WindowBuilder::new() 86 | .with_dimensions(1024, 768) 87 | .with_srgb(Some(true)) 88 | .with_title("Tutorial 08") 89 | .build_glium() 90 | .unwrap(); 91 | 92 | // Create a vertex buffer 93 | let vertex_buffer = create_vertex_buffer(&display); 94 | 95 | // Create a shader program 96 | let program = create_shaders(&display); 97 | 98 | // Main loop 99 | let mut scale: f32 = 0.0; 100 | loop { 101 | // Change the scale 102 | // (I use a smaller factor than the one used in the original source code 103 | // since the original factor is too large in my case) 104 | scale += 0.0001; 105 | 106 | // Render 107 | render_scene(&display, &vertex_buffer, &program, scale); 108 | 109 | // Handle events 110 | for event in display.poll_events() { 111 | match event { 112 | Event::Closed => return, 113 | _ => () 114 | } 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/bin/tutorial_09.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate cgmath; 4 | 5 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 6 | use glium::glutin::{Event, WindowBuilder}; 7 | use glium::index::{NoIndices, PrimitiveType}; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | use cgmath::{Matrix, Matrix4}; 10 | 11 | // Represent a 3D vertex 12 | #[derive(Copy, Clone)] 13 | struct Vertex { 14 | position: [f32; 3] 15 | } 16 | 17 | // Let glium implement Vertex for us 18 | implement_vertex!(Vertex, position); 19 | 20 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 21 | let vertices = vec![ 22 | Vertex { position: [-1.0, -1.0, 0.0] }, 23 | Vertex { position: [1.0, -1.0, 0.0] }, 24 | Vertex { position: [0.0, 1.0, 0.0] } 25 | ]; 26 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 27 | vertex_buffer 28 | } 29 | 30 | fn create_shaders(display: &GlutinFacade) -> Program { 31 | let vertex_shader_src = r#" 32 | #version 330 33 | 34 | layout (location = 0) in vec3 position; 35 | 36 | uniform mat4 gWorld; 37 | 38 | out vec4 color; 39 | 40 | void main() { 41 | gl_Position = gWorld * vec4(position, 1.0); 42 | color = vec4(clamp(position, 0.0, 1.0), 1.0); 43 | } 44 | "#; 45 | 46 | let fragment_shader_src = r#" 47 | #version 330 48 | 49 | in vec4 color; 50 | 51 | out vec4 fragColor; 52 | 53 | void main() { 54 | fragColor = color; 55 | } 56 | "#; 57 | 58 | Program::from_source(display, 59 | vertex_shader_src, fragment_shader_src, None).unwrap() 60 | } 61 | 62 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, program: &Program, 63 | scale: f32) { 64 | 65 | // Build the transform matrix 66 | // Note that the matrix is in column-major order 67 | // so you need to transpose it for OpenGL 68 | let sin_scale = scale.sin(); 69 | let world: [[f32; 4]; 4] = Matrix4::new( 70 | sin_scale, 0.0, 0.0, 0.0, 71 | 0.0, sin_scale, 0.0, 0.0, 72 | 0.0, 0.0, sin_scale, 0.0, 73 | 0.0, 0.0, 0.0, 1.0 74 | ).transpose().into(); 75 | 76 | let uniform = uniform!{ gWorld: world }; 77 | 78 | let mut frame = display.draw(); 79 | 80 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 81 | 82 | frame.draw(vertex_buffer, &NoIndices(PrimitiveType::TrianglesList), program, 83 | &uniform, &Default::default()).unwrap(); 84 | 85 | frame.finish().unwrap(); 86 | } 87 | 88 | fn main() { 89 | // Set up and create a window 90 | let display = WindowBuilder::new() 91 | .with_dimensions(1024, 768) 92 | .with_srgb(Some(true)) 93 | .with_title("Tutorial 09") 94 | .build_glium() 95 | .unwrap(); 96 | 97 | // Create a vertex buffer 98 | let vertex_buffer = create_vertex_buffer(&display); 99 | 100 | // Create a shader program 101 | let program = create_shaders(&display); 102 | 103 | // Main loop 104 | let mut scale: f32 = 0.0; 105 | loop { 106 | // Change the scale 107 | // (I use a smaller factor than the one used in the original source code 108 | // since the original factor is too large in my case) 109 | scale += 0.0001; 110 | 111 | // Render 112 | render_scene(&display, &vertex_buffer, &program, scale); 113 | 114 | // Handle events 115 | for event in display.poll_events() { 116 | match event { 117 | Event::Closed => return, 118 | _ => () 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/bin/tutorial_10.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate cgmath; 4 | 5 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 6 | use glium::glutin::{Event, WindowBuilder}; 7 | use glium::index::{IndexBuffer, PrimitiveType}; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | use cgmath::{Matrix, Matrix4}; 10 | 11 | // Represent a 3D vertex 12 | #[derive(Copy, Clone)] 13 | struct Vertex { 14 | position: [f32; 3] 15 | } 16 | 17 | // Let glium implement Vertex for us 18 | implement_vertex!(Vertex, position); 19 | 20 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 21 | let vertices = vec![ 22 | Vertex { position: [-1.0, -1.0, 0.0] }, 23 | Vertex { position: [0.0, -1.0, 1.0] }, 24 | Vertex { position: [1.0, -1.0, 0.0] }, 25 | Vertex { position: [0.0, 1.0, 0.0] } 26 | ]; 27 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 28 | vertex_buffer 29 | } 30 | 31 | fn create_index_buffer(display: &GlutinFacade) -> IndexBuffer { 32 | let indcies = vec![ 33 | 0, 3, 1, 34 | 1, 3, 2, 35 | 2, 3, 0, 36 | 0, 1, 2 37 | ]; 38 | let index_buffer = IndexBuffer::new(display, PrimitiveType::TrianglesList, &indcies).unwrap(); 39 | index_buffer 40 | } 41 | 42 | fn create_shaders(display: &GlutinFacade) -> Program { 43 | let vertex_shader_src = r#" 44 | #version 330 45 | 46 | layout (location = 0) in vec3 position; 47 | 48 | uniform mat4 gWorld; 49 | 50 | out vec4 color; 51 | 52 | void main() { 53 | gl_Position = gWorld * vec4(position, 1.0); 54 | color = vec4(clamp(position, 0.0, 1.0), 1.0); 55 | } 56 | "#; 57 | 58 | let fragment_shader_src = r#" 59 | #version 330 60 | 61 | in vec4 color; 62 | 63 | out vec4 fragColor; 64 | 65 | void main() { 66 | fragColor = color; 67 | } 68 | "#; 69 | 70 | Program::from_source(display, 71 | vertex_shader_src, fragment_shader_src, None).unwrap() 72 | } 73 | 74 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, 75 | index_buffer: &IndexBuffer, program: &Program, scale: f32) { 76 | 77 | // Build the transform matrix 78 | // Note that the matrix is in column-major order 79 | // so you need to transpose it for OpenGL 80 | let sin_scale = scale.sin(); 81 | let cos_scale = scale.cos(); 82 | let world: [[f32; 4]; 4] = Matrix4::new( 83 | cos_scale, 0.0, -sin_scale, 0.0, 84 | 0.0, 1.0, 0.0, 0.0, 85 | sin_scale, 0.0, cos_scale, 0.0, 86 | 0.0, 0.0, 0.0, 1.0 87 | ).transpose().into(); 88 | 89 | let uniform = uniform!{ gWorld: world }; 90 | 91 | let mut frame = display.draw(); 92 | 93 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 94 | 95 | frame.draw(vertex_buffer, index_buffer, program, 96 | &uniform, &Default::default()).unwrap(); 97 | 98 | frame.finish().unwrap(); 99 | } 100 | 101 | fn main() { 102 | // Set up and create a window 103 | let display = WindowBuilder::new() 104 | .with_dimensions(1024, 768) 105 | .with_srgb(Some(true)) 106 | .with_title("Tutorial 10") 107 | .build_glium() 108 | .unwrap(); 109 | 110 | // Create a vertex buffer and indices 111 | let vertex_buffer = create_vertex_buffer(&display); 112 | let index_buffer = create_index_buffer(&display); 113 | 114 | // Create a shader program 115 | let program = create_shaders(&display); 116 | 117 | // Main loop 118 | let mut scale: f32 = 0.0; 119 | loop { 120 | // Change the scale 121 | // (I use a smaller factor than the one used in the original source code 122 | // since the original factor is too large in my case) 123 | scale += 0.0001; 124 | 125 | // Render 126 | render_scene(&display, &vertex_buffer, &index_buffer, &program, scale); 127 | 128 | // Handle events 129 | for event in display.poll_events() { 130 | match event { 131 | Event::Closed => return, 132 | _ => () 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/bin/tutorial_11.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate cgmath; 4 | extern crate ogldev; 5 | 6 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 7 | use glium::glutin::{Event, WindowBuilder}; 8 | use glium::index::{IndexBuffer, PrimitiveType}; 9 | use glium::backend::glutin_backend::GlutinFacade; 10 | 11 | use ogldev::Pipeline; 12 | 13 | // Represent a 3D vertex 14 | #[derive(Copy, Clone)] 15 | struct Vertex { 16 | position: [f32; 3] 17 | } 18 | 19 | // Let glium implement Vertex for us 20 | implement_vertex!(Vertex, position); 21 | 22 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 23 | let vertices = vec![ 24 | Vertex { position: [-1.0, -1.0, 0.0] }, 25 | Vertex { position: [0.0, -1.0, 1.0] }, 26 | Vertex { position: [1.0, -1.0, 0.0] }, 27 | Vertex { position: [0.0, 1.0, 0.0] } 28 | ]; 29 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 30 | vertex_buffer 31 | } 32 | 33 | fn create_index_buffer(display: &GlutinFacade) -> IndexBuffer { 34 | let indcies = vec![ 35 | 0, 3, 1, 36 | 1, 3, 2, 37 | 2, 3, 0, 38 | 0, 1, 2 39 | ]; 40 | let index_buffer = IndexBuffer::new(display, PrimitiveType::TrianglesList, &indcies).unwrap(); 41 | index_buffer 42 | } 43 | 44 | fn create_shaders(display: &GlutinFacade) -> Program { 45 | let vertex_shader_src = r#" 46 | #version 330 47 | 48 | layout (location = 0) in vec3 position; 49 | 50 | uniform mat4 gWorld; 51 | 52 | out vec4 color; 53 | 54 | void main() { 55 | gl_Position = gWorld * vec4(position, 1.0); 56 | color = vec4(clamp(position, 0.0, 1.0), 1.0); 57 | } 58 | "#; 59 | 60 | let fragment_shader_src = r#" 61 | #version 330 62 | 63 | in vec4 color; 64 | 65 | out vec4 fragColor; 66 | 67 | void main() { 68 | fragColor = color; 69 | } 70 | "#; 71 | 72 | Program::from_source(display, 73 | vertex_shader_src, fragment_shader_src, None).unwrap() 74 | } 75 | 76 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, 77 | index_buffer: &IndexBuffer, program: &Program, scale: f32) { 78 | 79 | // Create a Pipeline 80 | let mut pipeline = Pipeline::new(); 81 | pipeline.scale((scale * 0.1).sin(), (scale * 0.1).sin(), (scale * 0.1).sin()); 82 | pipeline.world_pos(scale.sin(), 0.0, 0.0); 83 | pipeline.rotate(scale.sin() * 90.0, scale.sin() * 90.0, scale.sin() * 90.0); 84 | 85 | // Set the uniform matrix 86 | let world: [[f32; 4]; 4] = pipeline.get_world_trans().into(); 87 | let uniform = uniform!{ gWorld: world }; 88 | 89 | // Drawing 90 | let mut frame = display.draw(); 91 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 92 | frame.draw(vertex_buffer, index_buffer, program, 93 | &uniform, &Default::default()).unwrap(); 94 | frame.finish().unwrap(); 95 | } 96 | 97 | fn main() { 98 | // Set up and create a window 99 | let display = WindowBuilder::new() 100 | .with_dimensions(1024, 768) 101 | .with_srgb(Some(true)) 102 | .with_title("Tutorial 11") 103 | .build_glium() 104 | .unwrap(); 105 | 106 | // Create a vertex buffer and indices 107 | let vertex_buffer = create_vertex_buffer(&display); 108 | let index_buffer = create_index_buffer(&display); 109 | 110 | // Create a shader program 111 | let program = create_shaders(&display); 112 | 113 | // Main loop 114 | let mut scale: f32 = 0.0; 115 | loop { 116 | // Change the scale 117 | // (I use a smaller factor than the one used in the original source code 118 | // since the original factor is too large in my case) 119 | scale += 0.0001; 120 | 121 | // Render 122 | render_scene(&display, &vertex_buffer, &index_buffer, &program, scale); 123 | 124 | // Handle events 125 | for event in display.poll_events() { 126 | match event { 127 | Event::Closed => return, 128 | _ => () 129 | } 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/bin/tutorial_12.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate cgmath; 4 | extern crate ogldev; 5 | 6 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 7 | use glium::glutin::{Event, WindowBuilder}; 8 | use glium::index::{IndexBuffer, PrimitiveType}; 9 | use glium::backend::glutin_backend::GlutinFacade; 10 | 11 | use ogldev::Pipeline; 12 | 13 | const WINDOW_WIDTH: u32 = 1024; 14 | const WINDOW_HEIGHT: u32 = 768; 15 | 16 | // Represent a 3D vertex 17 | #[derive(Copy, Clone)] 18 | struct Vertex { 19 | position: [f32; 3] 20 | } 21 | 22 | // Let glium implement Vertex for us 23 | implement_vertex!(Vertex, position); 24 | 25 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 26 | let vertices = vec![ 27 | Vertex { position: [-1.0, -1.0, 0.0] }, 28 | Vertex { position: [0.0, -1.0, 1.0] }, 29 | Vertex { position: [1.0, -1.0, 0.0] }, 30 | Vertex { position: [0.0, 1.0, 0.0] } 31 | ]; 32 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 33 | vertex_buffer 34 | } 35 | 36 | fn create_index_buffer(display: &GlutinFacade) -> IndexBuffer { 37 | let indcies = vec![ 38 | 0, 3, 1, 39 | 1, 3, 2, 40 | 2, 3, 0, 41 | 0, 1, 2 42 | ]; 43 | let index_buffer = IndexBuffer::new(display, PrimitiveType::TrianglesList, &indcies).unwrap(); 44 | index_buffer 45 | } 46 | 47 | fn create_shaders(display: &GlutinFacade) -> Program { 48 | let vertex_shader_src = r#" 49 | #version 330 50 | 51 | layout (location = 0) in vec3 position; 52 | 53 | uniform mat4 gWorld; 54 | 55 | out vec4 color; 56 | 57 | void main() { 58 | gl_Position = gWorld * vec4(position, 1.0); 59 | color = vec4(clamp(position, 0.0, 1.0), 1.0); 60 | } 61 | "#; 62 | 63 | let fragment_shader_src = r#" 64 | #version 330 65 | 66 | in vec4 color; 67 | 68 | out vec4 fragColor; 69 | 70 | void main() { 71 | fragColor = color; 72 | } 73 | "#; 74 | 75 | Program::from_source(display, 76 | vertex_shader_src, fragment_shader_src, None).unwrap() 77 | } 78 | 79 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, 80 | index_buffer: &IndexBuffer, program: &Program, scale: f32) { 81 | 82 | // Create a Pipeline 83 | let mut pipeline = Pipeline::new(); 84 | pipeline.rotate(0.0, scale, 0.0); 85 | pipeline.world_pos(0.0, 0.0, 5.0); 86 | pipeline.set_perspective_proj(30.0, WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32, 1.0, 1000.0); 87 | 88 | // Set the uniform matrix 89 | let world: [[f32; 4]; 4] = pipeline.get_wp_trans().into(); 90 | let uniform = uniform!{ gWorld: world }; 91 | 92 | // Drawing 93 | let mut frame = display.draw(); 94 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 95 | frame.draw(vertex_buffer, index_buffer, program, 96 | &uniform, &Default::default()).unwrap(); 97 | frame.finish().unwrap(); 98 | } 99 | 100 | fn main() { 101 | // Set up and create a window 102 | let display = WindowBuilder::new() 103 | .with_dimensions(WINDOW_WIDTH, WINDOW_HEIGHT) 104 | .with_srgb(Some(true)) 105 | .with_title("Tutorial 12") 106 | .build_glium() 107 | .unwrap(); 108 | 109 | // Create a vertex buffer and indices 110 | let vertex_buffer = create_vertex_buffer(&display); 111 | let index_buffer = create_index_buffer(&display); 112 | 113 | // Create a shader program 114 | let program = create_shaders(&display); 115 | 116 | // Main loop 117 | let mut scale: f32 = 0.0; 118 | loop { 119 | // Change the scale 120 | // (I use a smaller factor than the one used in the original source code 121 | // since the original factor is too large in my case) 122 | scale += 0.01; 123 | 124 | // Render 125 | render_scene(&display, &vertex_buffer, &index_buffer, &program, scale); 126 | 127 | // Handle events 128 | for event in display.poll_events() { 129 | match event { 130 | Event::Closed => return, 131 | _ => () 132 | } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/bin/tutorial_13.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate cgmath; 4 | extern crate ogldev; 5 | 6 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 7 | use glium::glutin::{Event, WindowBuilder}; 8 | use glium::index::{IndexBuffer, PrimitiveType}; 9 | use glium::backend::glutin_backend::GlutinFacade; 10 | 11 | use cgmath::{Vector3}; 12 | 13 | use ogldev::Pipeline; 14 | 15 | const WINDOW_WIDTH: u32 = 1024; 16 | const WINDOW_HEIGHT: u32 = 768; 17 | 18 | // Represent a 3D vertex 19 | #[derive(Copy, Clone)] 20 | struct Vertex { 21 | position: [f32; 3] 22 | } 23 | 24 | // Let glium implement Vertex for us 25 | implement_vertex!(Vertex, position); 26 | 27 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 28 | let vertices = vec![ 29 | Vertex { position: [-1.0, -1.0, 0.0] }, 30 | Vertex { position: [0.0, -1.0, 1.0] }, 31 | Vertex { position: [1.0, -1.0, 0.0] }, 32 | Vertex { position: [0.0, 1.0, 0.0] } 33 | ]; 34 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 35 | vertex_buffer 36 | } 37 | 38 | fn create_index_buffer(display: &GlutinFacade) -> IndexBuffer { 39 | let indcies = vec![ 40 | 0, 3, 1, 41 | 1, 3, 2, 42 | 2, 3, 0, 43 | 0, 1, 2 44 | ]; 45 | let index_buffer = IndexBuffer::new(display, PrimitiveType::TrianglesList, &indcies).unwrap(); 46 | index_buffer 47 | } 48 | 49 | fn create_shaders(display: &GlutinFacade) -> Program { 50 | let vertex_shader_src = r#" 51 | #version 330 52 | 53 | layout (location = 0) in vec3 position; 54 | 55 | uniform mat4 gWVP; 56 | 57 | out vec4 color; 58 | 59 | void main() { 60 | gl_Position = gWVP * vec4(position, 1.0); 61 | color = vec4(clamp(position, 0.0, 1.0), 1.0); 62 | } 63 | "#; 64 | 65 | let fragment_shader_src = r#" 66 | #version 330 67 | 68 | in vec4 color; 69 | 70 | out vec4 fragColor; 71 | 72 | void main() { 73 | fragColor = color; 74 | } 75 | "#; 76 | 77 | Program::from_source(display, 78 | vertex_shader_src, fragment_shader_src, None).unwrap() 79 | } 80 | 81 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, 82 | index_buffer: &IndexBuffer, program: &Program, scale: f32) { 83 | 84 | // Create a Pipeline 85 | let mut pipeline = Pipeline::new(); 86 | pipeline.rotate(0.0, scale, 0.0); 87 | pipeline.world_pos(0.0, 0.0, 3.0); 88 | let camera_pos = Vector3::new(0.0, 0.0, -3.0); 89 | let camera_target = Vector3::new(0.0, 0.0, 2.0); 90 | let camera_up = Vector3::new(0.0, 1.0, 0.0); 91 | pipeline.set_camera(camera_pos, camera_target, camera_up); 92 | pipeline.set_perspective_proj(60.0, WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32, 1.0, 100.0); 93 | 94 | // Set the uniform matrix 95 | let wvp: [[f32; 4]; 4] = pipeline.get_wvp_trans().into(); 96 | let uniform = uniform!{ gWVP: wvp }; 97 | 98 | // Drawing 99 | let mut frame = display.draw(); 100 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 101 | frame.draw(vertex_buffer, index_buffer, program, 102 | &uniform, &Default::default()).unwrap(); 103 | frame.finish().unwrap(); 104 | } 105 | 106 | fn main() { 107 | // Set up and create a window 108 | let display = WindowBuilder::new() 109 | .with_dimensions(WINDOW_WIDTH, WINDOW_HEIGHT) 110 | .with_srgb(Some(true)) 111 | .with_title("Tutorial 13") 112 | .build_glium() 113 | .unwrap(); 114 | 115 | // Create a vertex buffer and indices 116 | let vertex_buffer = create_vertex_buffer(&display); 117 | let index_buffer = create_index_buffer(&display); 118 | 119 | // Create a shader program 120 | let program = create_shaders(&display); 121 | 122 | // Main loop 123 | let mut scale: f32 = 0.0; 124 | loop { 125 | // Change the scale 126 | // (I use a smaller factor than the one used in the original source code 127 | // since the original factor is too large in my case) 128 | scale += 0.01; 129 | 130 | // Render 131 | render_scene(&display, &vertex_buffer, &index_buffer, &program, scale); 132 | 133 | // Handle events 134 | for event in display.poll_events() { 135 | match event { 136 | Event::Closed => return, 137 | _ => () 138 | } 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/bin/tutorial_14.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate ogldev; 4 | 5 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 6 | use glium::glutin::{Event, WindowBuilder}; 7 | use glium::index::{IndexBuffer, PrimitiveType}; 8 | use glium::backend::glutin_backend::GlutinFacade; 9 | 10 | use ogldev::{Camera, Pipeline}; 11 | 12 | const WINDOW_WIDTH: u32 = 1024; 13 | const WINDOW_HEIGHT: u32 = 768; 14 | 15 | // Represent a 3D vertex 16 | #[derive(Copy, Clone)] 17 | struct Vertex { 18 | position: [f32; 3] 19 | } 20 | 21 | // Let glium implement Vertex for us 22 | implement_vertex!(Vertex, position); 23 | 24 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 25 | let vertices = vec![ 26 | Vertex { position: [-1.0, -1.0, 0.0] }, 27 | Vertex { position: [0.0, -1.0, 1.0] }, 28 | Vertex { position: [1.0, -1.0, 0.0] }, 29 | Vertex { position: [0.0, 1.0, 0.0] } 30 | ]; 31 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 32 | vertex_buffer 33 | } 34 | 35 | fn create_index_buffer(display: &GlutinFacade) -> IndexBuffer { 36 | let indcies = vec![ 37 | 0, 3, 1, 38 | 1, 3, 2, 39 | 2, 3, 0, 40 | 0, 1, 2 41 | ]; 42 | let index_buffer = IndexBuffer::new(display, PrimitiveType::TrianglesList, &indcies).unwrap(); 43 | index_buffer 44 | } 45 | 46 | fn create_shaders(display: &GlutinFacade) -> Program { 47 | let vertex_shader_src = r#" 48 | #version 330 49 | 50 | layout (location = 0) in vec3 position; 51 | 52 | uniform mat4 gWVP; 53 | 54 | out vec4 color; 55 | 56 | void main() { 57 | gl_Position = gWVP * vec4(position, 1.0); 58 | color = vec4(clamp(position, 0.0, 1.0), 1.0); 59 | } 60 | "#; 61 | 62 | let fragment_shader_src = r#" 63 | #version 330 64 | 65 | in vec4 color; 66 | 67 | out vec4 fragColor; 68 | 69 | void main() { 70 | fragColor = color; 71 | } 72 | "#; 73 | 74 | Program::from_source(display, 75 | vertex_shader_src, fragment_shader_src, None).unwrap() 76 | } 77 | 78 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, 79 | index_buffer: &IndexBuffer, program: &Program, camera: &Camera, scale: f32) { 80 | 81 | // Create a Pipeline 82 | let mut pipeline = Pipeline::new(); 83 | pipeline.rotate(0.0, scale, 0.0); 84 | pipeline.world_pos(0.0, 0.0, 3.0); 85 | pipeline.set_camera(camera.get_pos(), camera.get_target(), camera.get_up()); 86 | pipeline.set_perspective_proj(60.0, WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32, 1.0, 100.0); 87 | 88 | // Set the uniform matrix 89 | let wvp: [[f32; 4]; 4] = pipeline.get_wvp_trans().into(); 90 | let uniform = uniform!{ gWVP: wvp }; 91 | 92 | // Drawing 93 | let mut frame = display.draw(); 94 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 95 | frame.draw(vertex_buffer, index_buffer, program, 96 | &uniform, &Default::default()).unwrap(); 97 | frame.finish().unwrap(); 98 | } 99 | 100 | fn main() { 101 | // Set up and create a window 102 | let display = WindowBuilder::new() 103 | .with_dimensions(WINDOW_WIDTH, WINDOW_HEIGHT) 104 | .with_srgb(Some(true)) 105 | .with_title("Tutorial 14") 106 | .build_glium() 107 | .unwrap(); 108 | 109 | // Create a vertex buffer and indices 110 | let vertex_buffer = create_vertex_buffer(&display); 111 | let index_buffer = create_index_buffer(&display); 112 | 113 | // Create a shader program 114 | let program = create_shaders(&display); 115 | 116 | // Create a camera 117 | let mut camera = Camera::default(WINDOW_WIDTH, WINDOW_HEIGHT); 118 | 119 | // Main loop 120 | let mut scale: f32 = 0.0; 121 | loop { 122 | // Change the scale 123 | // (I use a smaller factor than the one used in the original source code 124 | // since the original factor is too large in my case) 125 | scale += 0.01; 126 | 127 | // Render 128 | render_scene(&display, &vertex_buffer, &index_buffer, &program, &camera, scale); 129 | 130 | // Handle events 131 | for event in display.poll_events() { 132 | match event { 133 | Event::Closed => return, 134 | Event::KeyboardInput(_, _, Some(key)) => { 135 | camera.on_key_board(key); 136 | }, 137 | _ => () 138 | } 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/bin/tutorial_15.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate ogldev; 4 | 5 | use glium::{DisplayBuild, Surface, VertexBuffer, Program}; 6 | use glium::glutin; 7 | use glium::glutin::{Event, WindowBuilder, VirtualKeyCode}; 8 | use glium::index::{IndexBuffer, PrimitiveType}; 9 | use glium::backend::glutin_backend::GlutinFacade; 10 | 11 | use ogldev::{Camera, Pipeline}; 12 | 13 | const WINDOW_WIDTH: u32 = 1920; 14 | const WINDOW_HEIGHT: u32 = 1080; 15 | 16 | // Represent a 3D vertex 17 | #[derive(Copy, Clone)] 18 | struct Vertex { 19 | position: [f32; 3] 20 | } 21 | 22 | // Let glium implement Vertex for us 23 | implement_vertex!(Vertex, position); 24 | 25 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 26 | let vertices = vec![ 27 | Vertex { position: [-1.0, -1.0, 0.0] }, 28 | Vertex { position: [0.0, -1.0, 1.0] }, 29 | Vertex { position: [1.0, -1.0, 0.0] }, 30 | Vertex { position: [0.0, 1.0, 0.0] } 31 | ]; 32 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 33 | vertex_buffer 34 | } 35 | 36 | fn create_index_buffer(display: &GlutinFacade) -> IndexBuffer { 37 | let indcies = vec![ 38 | 0, 3, 1, 39 | 1, 3, 2, 40 | 2, 3, 0, 41 | 0, 1, 2 42 | ]; 43 | let index_buffer = IndexBuffer::new(display, PrimitiveType::TrianglesList, &indcies).unwrap(); 44 | index_buffer 45 | } 46 | 47 | fn create_shaders(display: &GlutinFacade) -> Program { 48 | let vertex_shader_src = r#" 49 | #version 330 50 | 51 | layout (location = 0) in vec3 position; 52 | 53 | uniform mat4 gWVP; 54 | 55 | out vec4 color; 56 | 57 | void main() { 58 | gl_Position = gWVP * vec4(position, 1.0); 59 | color = vec4(clamp(position, 0.0, 1.0), 1.0); 60 | } 61 | "#; 62 | 63 | let fragment_shader_src = r#" 64 | #version 330 65 | 66 | in vec4 color; 67 | 68 | out vec4 fragColor; 69 | 70 | void main() { 71 | fragColor = color; 72 | } 73 | "#; 74 | 75 | Program::from_source(display, 76 | vertex_shader_src, fragment_shader_src, None).unwrap() 77 | } 78 | 79 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, 80 | index_buffer: &IndexBuffer, program: &Program, camera: &mut Camera, scale: f32) { 81 | 82 | // Notify the camera 83 | camera.on_render(); 84 | 85 | // Create a Pipeline 86 | let mut pipeline = Pipeline::new(); 87 | pipeline.rotate(0.0, scale, 0.0); 88 | pipeline.world_pos(0.0, 0.0, 3.0); 89 | pipeline.set_camera(camera.get_pos(), camera.get_target(), camera.get_up()); 90 | pipeline.set_perspective_proj(60.0, WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32, 1.0, 100.0); 91 | 92 | // Set the uniform matrix 93 | let wvp: [[f32; 4]; 4] = pipeline.get_wvp_trans().into(); 94 | let uniform = uniform!{ gWVP: wvp }; 95 | 96 | // Drawing 97 | let mut frame = display.draw(); 98 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 99 | frame.draw(vertex_buffer, index_buffer, program, 100 | &uniform, &Default::default()).unwrap(); 101 | frame.finish().unwrap(); 102 | } 103 | 104 | fn main() { 105 | // Set up and create a window 106 | let display = WindowBuilder::new() 107 | .with_dimensions(WINDOW_WIDTH, WINDOW_HEIGHT) 108 | .with_fullscreen(glutin::get_primary_monitor()) 109 | .with_srgb(Some(true)) 110 | .with_title("Tutorial 15") 111 | .build_glium() 112 | .unwrap(); 113 | 114 | // Create a vertex buffer and indices 115 | let vertex_buffer = create_vertex_buffer(&display); 116 | let index_buffer = create_index_buffer(&display); 117 | 118 | // Create a shader program 119 | let program = create_shaders(&display); 120 | 121 | // Create a camera 122 | let mut camera = Camera::default(WINDOW_WIDTH, WINDOW_HEIGHT); 123 | 124 | // Main loop 125 | let mut scale: f32 = 0.0; 126 | loop { 127 | // Change the scale 128 | // (I use a smaller factor than the one used in the original source code 129 | // since the original factor is too large in my case) 130 | scale += 0.01; 131 | 132 | // Render 133 | render_scene(&display, &vertex_buffer, &index_buffer, &program, &mut camera, scale); 134 | 135 | // Handle events 136 | for event in display.poll_events() { 137 | match event { 138 | Event::Closed => return, 139 | Event::KeyboardInput(_, _, Some(VirtualKeyCode::Q)) => { 140 | std::process::exit(0); 141 | }, 142 | Event::KeyboardInput(_, _, Some(key)) => { 143 | camera.on_key_board(key); 144 | }, 145 | Event::MouseMoved(x, y) => { 146 | camera.on_mouse(x, y); 147 | }, 148 | _ => () 149 | } 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/bin/tutorial_16.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate glium; 3 | extern crate ogldev; 4 | extern crate image; 5 | 6 | use std::path::Path; 7 | 8 | use glium::{DisplayBuild, Surface, VertexBuffer, Program, DrawParameters}; 9 | use glium::glutin::{Event, WindowBuilder, VirtualKeyCode}; 10 | use glium::index::{IndexBuffer, PrimitiveType}; 11 | use glium::backend::glutin_backend::GlutinFacade; 12 | use glium::texture::{RawImage2d, Texture2d}; 13 | use glium::draw_parameters::BackfaceCullingMode; 14 | 15 | use ogldev::{Camera, Pipeline}; 16 | 17 | const WINDOW_WIDTH: u32 = 1280; 18 | const WINDOW_HEIGHT: u32 = 1024; 19 | 20 | // Represent a 3D vertex 21 | #[derive(Copy, Clone)] 22 | struct Vertex { 23 | position: [f32; 3], 24 | tex_coords: [f32; 2] 25 | } 26 | 27 | // Let glium implement Vertex for us 28 | implement_vertex!(Vertex, position, tex_coords); 29 | 30 | fn create_vertex_buffer(display: &GlutinFacade) -> VertexBuffer { 31 | let vertices = vec![ 32 | Vertex { position: [-1.0, -1.0, 0.5773], tex_coords: [0.0, 0.0] }, 33 | Vertex { position: [0.0, -1.0, -1.15475], tex_coords: [0.5, 0.0] }, 34 | Vertex { position: [1.0, -1.0, 0.5773], tex_coords: [1.0, 0.0] }, 35 | Vertex { position: [0.0, 1.0, 0.0], tex_coords: [0.5, 1.0] } 36 | ]; 37 | let vertex_buffer = VertexBuffer::new(display, &vertices).unwrap(); 38 | vertex_buffer 39 | } 40 | 41 | fn create_index_buffer(display: &GlutinFacade) -> IndexBuffer { 42 | let indcies = vec![ 43 | 0, 3, 1, 44 | 1, 3, 2, 45 | 2, 3, 0, 46 | 0, 1, 2 47 | ]; 48 | let index_buffer = IndexBuffer::new(display, PrimitiveType::TrianglesList, &indcies).unwrap(); 49 | index_buffer 50 | } 51 | 52 | fn create_shaders(display: &GlutinFacade) -> Program { 53 | let vertex_shader_src = r#" 54 | #version 330 55 | 56 | layout (location = 0) in vec3 position; 57 | layout (location = 1) in vec2 tex_coords; 58 | 59 | uniform mat4 gWVP; 60 | 61 | out vec2 texCoord0; 62 | 63 | void main() { 64 | gl_Position = gWVP * vec4(position, 1.0); 65 | texCoord0 = tex_coords; 66 | } 67 | "#; 68 | 69 | let fragment_shader_src = r#" 70 | #version 330 71 | 72 | in vec2 texCoord0; 73 | 74 | out vec4 fragColor; 75 | 76 | uniform sampler2D gSampler; 77 | 78 | void main() { 79 | fragColor = texture2D(gSampler, texCoord0.xy); 80 | } 81 | "#; 82 | 83 | Program::from_source(display, 84 | vertex_shader_src, fragment_shader_src, None).unwrap() 85 | } 86 | 87 | fn render_scene(display: &GlutinFacade, vertex_buffer: &VertexBuffer, 88 | index_buffer: &IndexBuffer, program: &Program, camera: &mut Camera, scale: f32, 89 | texture: &Texture2d, params: &DrawParameters) { 90 | 91 | // Notify the camera 92 | camera.on_render(); 93 | 94 | // Create a Pipeline 95 | let mut pipeline = Pipeline::new(); 96 | pipeline.rotate(0.0, scale, 0.0); 97 | pipeline.world_pos(0.0, 0.0, 3.0); 98 | pipeline.set_camera(camera.get_pos(), camera.get_target(), camera.get_up()); 99 | pipeline.set_perspective_proj(60.0, WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32, 1.0, 100.0); 100 | 101 | // Set the uniform matrix 102 | let wvp: [[f32; 4]; 4] = pipeline.get_wvp_trans().into(); 103 | let uniform = uniform!{ gWVP: wvp, gSampler: texture }; 104 | 105 | // Drawing 106 | let mut frame = display.draw(); 107 | frame.clear_color(0.0, 0.0, 0.0, 0.0); 108 | frame.draw(vertex_buffer, index_buffer, program, 109 | &uniform, params).unwrap(); 110 | frame.finish().unwrap(); 111 | } 112 | 113 | fn main() { 114 | // Set up and create a window 115 | let display = WindowBuilder::new() 116 | .with_dimensions(WINDOW_WIDTH, WINDOW_HEIGHT) 117 | .with_srgb(Some(true)) 118 | .with_title("Tutorial 16") 119 | .build_glium() 120 | .unwrap(); 121 | 122 | // Create a vertex buffer and indices 123 | let vertex_buffer = create_vertex_buffer(&display); 124 | let index_buffer = create_index_buffer(&display); 125 | 126 | // Create a shader program 127 | let program = create_shaders(&display); 128 | 129 | // Create a camera 130 | let mut camera = Camera::default(WINDOW_WIDTH, WINDOW_HEIGHT); 131 | 132 | // Setup culling backface 133 | // NOTE: Here is a little bit different from the original tutorial. The tutorial says that you 134 | // need to specify the front face is drawn clockwisely or counterclockwisely. However, in glium 135 | // , to cull back faces, you have to specify the way of identifying BACK FACES. That's why I 136 | // give `BackfaceCullingMode::CullCounterClockwise` here, instead of 137 | // `BackfaceCullingMode::CullClockwise`. You can try the effect of both parameters. 138 | let params = DrawParameters { 139 | backface_culling: BackfaceCullingMode::CullCounterClockwise, 140 | .. Default::default() 141 | }; 142 | 143 | // Load a texture 144 | let image = image::open(&Path::new("content/test.png")).unwrap().to_rgba(); 145 | let image_dim = image.dimensions(); 146 | let image = RawImage2d::from_raw_rgba_reversed(image.into_raw(), image_dim); 147 | let texture = Texture2d::new(&display, image).unwrap(); 148 | 149 | // Main loop 150 | let mut scale: f32 = 0.0; 151 | loop { 152 | // Change the scale 153 | // (I use a smaller factor than the one used in the original source code 154 | // since the original factor is too large in my case) 155 | scale += 0.01; 156 | 157 | // Render 158 | render_scene(&display, &vertex_buffer, &index_buffer, &program, &mut camera, scale, &texture, ¶ms); 159 | 160 | // Handle events 161 | for event in display.poll_events() { 162 | match event { 163 | Event::Closed => return, 164 | Event::KeyboardInput(_, _, Some(VirtualKeyCode::Q)) => { 165 | std::process::exit(0); 166 | }, 167 | Event::KeyboardInput(_, _, Some(key)) => { 168 | camera.on_key_board(key); 169 | }, 170 | Event::MouseMoved(x, y) => { 171 | camera.on_mouse(x, y); 172 | }, 173 | _ => () 174 | } 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/camera.rs: -------------------------------------------------------------------------------- 1 | 2 | use cgmath::{Deg, InnerSpace, Vector2, Vector3, Matrix3}; 3 | use glium::glutin::VirtualKeyCode; 4 | 5 | const STEP_SCALE: f32 = 0.2; 6 | const MARGIN: i32 = 10; 7 | 8 | pub struct Camera { 9 | // For View Transformation 10 | pos: Vector3, 11 | target: Vector3, 12 | up: Vector3, 13 | 14 | // For control the camera 15 | window_width: i32, 16 | window_height: i32, 17 | angle_h: f32, 18 | angle_v: f32, 19 | on_upper_edge: bool, 20 | on_lower_edge: bool, 21 | on_left_edge: bool, 22 | on_right_edge: bool, 23 | mouse_pos: Vector2 24 | } 25 | 26 | impl Camera { 27 | 28 | pub fn default(window_width: u32, window_height: u32) -> Camera { 29 | let mut camera = Camera { 30 | pos: Vector3::new(0.0, 0.0, 0.0), 31 | target: Vector3::new(0.0, 0.0, 1.0), 32 | up: Vector3::new(0.0, 1.0, 0.0), 33 | window_width: window_width as i32, 34 | window_height: window_height as i32, 35 | angle_h: 0.0, 36 | angle_v: 0.0, 37 | on_upper_edge: false, 38 | on_lower_edge: false, 39 | on_left_edge: false, 40 | on_right_edge: false, 41 | mouse_pos: Vector2::new(0, 0) 42 | }; 43 | 44 | camera.init(); 45 | camera 46 | } 47 | 48 | pub fn new(window_width: u32, window_height: u32, pos: Vector3, target: Vector3, up: Vector3) -> Camera { 49 | let mut camera = Self::default(window_width, window_height); 50 | camera.pos = pos; 51 | camera.target = target.normalize(); 52 | camera.up = up; 53 | 54 | camera.init(); 55 | camera 56 | } 57 | 58 | pub fn get_pos(&self) -> Vector3 { 59 | self.pos 60 | } 61 | 62 | pub fn get_target(&self) -> Vector3 { 63 | self.target 64 | } 65 | 66 | pub fn get_up(&self) -> Vector3 { 67 | self.up 68 | } 69 | 70 | pub fn on_key_board(&mut self, key: VirtualKeyCode) -> bool { 71 | match key { 72 | VirtualKeyCode::Up => { 73 | self.pos += self.target * STEP_SCALE; 74 | true 75 | }, 76 | VirtualKeyCode::Down => { 77 | self.pos -= self.target * STEP_SCALE; 78 | true 79 | }, 80 | VirtualKeyCode::Left => { 81 | let mut left = self.target.cross(self.up); 82 | left = left.normalize(); 83 | left *= STEP_SCALE; 84 | self.pos += left; 85 | true 86 | }, 87 | VirtualKeyCode::Right => { 88 | let mut right = self.up.cross(self.target); 89 | right = right.normalize(); 90 | right *= STEP_SCALE; 91 | self.pos += right; 92 | true 93 | }, 94 | _ => false 95 | } 96 | } 97 | 98 | pub fn on_mouse(&mut self, x: i32, y: i32) { 99 | let delta_x = x - self.mouse_pos.x; 100 | let delta_y = y - self.mouse_pos.y; 101 | 102 | self.mouse_pos.x = x; 103 | self.mouse_pos.y = y; 104 | 105 | self.angle_h += (delta_x as f32) / 20.0; 106 | self.angle_v += (delta_y as f32) / 20.0; 107 | 108 | // Horizontal edge detection 109 | if delta_x == 0 { 110 | if x <= MARGIN { 111 | self.on_left_edge = true; 112 | } else if x >= (self.window_width - MARGIN) { 113 | self.on_right_edge = true; 114 | } 115 | } else { 116 | self.on_left_edge = false; 117 | self.on_right_edge = false; 118 | } 119 | 120 | // Vertical edge detection 121 | if delta_y == 0 { 122 | if y <= MARGIN { 123 | self.on_upper_edge = true; 124 | } else if y >= (self.window_height - MARGIN) { 125 | self.on_lower_edge = true; 126 | } 127 | } else { 128 | self.on_upper_edge = false; 129 | self.on_lower_edge = false; 130 | } 131 | 132 | self.update(); 133 | } 134 | 135 | pub fn on_render(&mut self) { 136 | let mut should_update = false; 137 | 138 | if self.on_left_edge { 139 | self.angle_h -= 0.1; 140 | should_update = true; 141 | } else if self.on_right_edge { 142 | self.angle_h += 0.1; 143 | should_update = true; 144 | } 145 | 146 | if self.on_upper_edge { 147 | if self.angle_v > -90.0 { 148 | self.angle_v -= 0.1; 149 | should_update = true; 150 | } 151 | } else if self.on_lower_edge { 152 | if self.angle_v < 90.0 { 153 | self.angle_v += 0.1; 154 | should_update = true; 155 | } 156 | } 157 | 158 | if should_update { 159 | self.update(); 160 | } 161 | } 162 | 163 | fn init(&mut self) { 164 | let h_target = Vector3::new(self.target.x, 0.0, self.target.z).normalize(); 165 | 166 | if h_target.z >= 0.0 { 167 | if h_target.x >= 0.0 { 168 | self.angle_h = 360.0 - h_target.z.asin().to_degrees(); 169 | } else { 170 | self.angle_h = 180.0 - h_target.z.asin().to_degrees(); 171 | } 172 | } else { 173 | if h_target.x >= 0.0 { 174 | self.angle_h = (-h_target.z).asin().to_degrees(); 175 | } else { 176 | self.angle_h = 90.0 + (-h_target.z).asin().to_degrees(); 177 | } 178 | } 179 | 180 | self.angle_v = - h_target.y.asin().to_degrees(); 181 | 182 | // NOTE: The flags for edges have been initialized in default() 183 | 184 | self.mouse_pos.x = self.window_width / 2; 185 | self.mouse_pos.y = self.window_height / 2; 186 | } 187 | 188 | fn update(&mut self) { 189 | let v_axis = Vector3::new(0.0, 1.0, 0.0); 190 | 191 | // Rotate the view vector by the horizontal angle around the vertical axis 192 | let mut view = Vector3::new(1.0, 0.0, 0.0); 193 | // There is something different here. Crate cgmath provides another way to rotate a vector 194 | // using a transfromation matrix. So this looks different from the original tutorial 195 | let mut rotate_matrix = Matrix3::from_axis_angle(v_axis, Deg(self.angle_h)); 196 | view = rotate_matrix * view; 197 | view = view.normalize(); 198 | 199 | // Rotate the view vector by the vertical angle around the horizontal axis 200 | let mut h_axis = v_axis.cross(view); 201 | h_axis = h_axis.normalize(); 202 | rotate_matrix = Matrix3::from_axis_angle(h_axis, Deg(self.angle_v)); 203 | view = rotate_matrix * view; 204 | view = view.normalize(); 205 | 206 | self.target = view; 207 | self.up = self.target.cross(h_axis).normalize(); 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /src/graphical_math.rs: -------------------------------------------------------------------------------- 1 | 2 | use cgmath::{InnerSpace, Vector3, Matrix, Matrix4}; 3 | 4 | #[derive(Default, Clone, Copy)] 5 | pub struct PersProjInfo { 6 | pub fov: f32, 7 | pub width: f32, 8 | pub height: f32, 9 | pub z_near: f32, 10 | pub z_far: f32 11 | } 12 | 13 | pub fn init_scale_transform(scale_x: f32, scale_y: f32, scale_z: f32) -> Matrix4 { 14 | Matrix4::new( 15 | scale_x, 0.0, 0.0, 0.0, 16 | 0.0, scale_y, 0.0, 0.0, 17 | 0.0, 0.0, scale_z, 0.0, 18 | 0.0, 0.0, 0.0, 1.0 19 | ).transpose() 20 | } 21 | 22 | pub fn init_rotate_transform(rotate_x: f32, rotate_y: f32, rotate_z: f32) -> Matrix4 { 23 | let x = rotate_x.to_radians(); 24 | let y = rotate_y.to_radians(); 25 | let z = rotate_z.to_radians(); 26 | 27 | let rx = Matrix4::new( 28 | 1.0, 0.0, 0.0, 0.0, 29 | 0.0, x.cos(), -x.sin(), 0.0, 30 | 0.0, x.sin(), x.cos(), 0.0, 31 | 0.0, 0.0, 0.0, 1.0 32 | ).transpose(); 33 | 34 | let ry = Matrix4::new( 35 | y.cos(), 0.0, -y.sin(), 0.0, 36 | 0.0, 1.0, 0.0, 0.0, 37 | y.sin(), 0.0, y.cos(), 0.0, 38 | 0.0, 0.0, 0.0, 1.0 39 | ).transpose(); 40 | 41 | let rz = Matrix4::new( 42 | z.cos(), -z.sin(), 0.0, 0.0, 43 | z.sin(), z.cos(), 0.0, 0.0, 44 | 0.0, 0.0, 1.0, 0.0, 45 | 0.0, 0.0, 0.0, 1.0 46 | ).transpose(); 47 | 48 | rz * ry * rx 49 | } 50 | 51 | pub fn init_translation_transform(x: f32, y: f32, z: f32) -> Matrix4 { 52 | Matrix4::new( 53 | 1.0, 0.0, 0.0, x, 54 | 0.0, 1.0, 0.0, y, 55 | 0.0, 0.0, 1.0, z, 56 | 0.0, 0.0, 0.0, 1.0 57 | ).transpose() 58 | } 59 | 60 | pub fn init_pers_proj_transform(p: PersProjInfo) -> Matrix4 { 61 | let ar = p.width / p.height; 62 | let z_range = p.z_near - p.z_far; 63 | let tan_half_fov = (p.fov / 2.0).to_radians().tan(); 64 | 65 | Matrix4::new( 66 | 1.0 / (tan_half_fov * ar), 0.0, 0.0, 0.0, 67 | 0.0, 1.0 / tan_half_fov, 0.0, 0.0, 68 | 0.0, 0.0, (-p.z_near - p.z_far) / z_range, 2.0 * p.z_far * p.z_near / z_range, 69 | 0.0, 0.0, 1.0, 0.0, 70 | ).transpose() 71 | } 72 | 73 | pub fn init_camera_transform(target: Vector3, up: Vector3) -> Matrix4 { 74 | let mut n: Vector3 = target; 75 | n = n.normalize(); 76 | let mut u: Vector3 = up; 77 | u = u.normalize(); 78 | u = u.cross(n); 79 | let v: Vector3 = n.cross(u); 80 | 81 | Matrix4::new( 82 | u.x, u.y, u.z, 0.0, 83 | v.x, v.y, v.z, 0.0, 84 | n.x, n.y, n.z, 0.0, 85 | 0.0, 0.0, 0.0, 1.0 86 | ).transpose() 87 | } 88 | 89 | // == Matrix Tamplate == 90 | // Matrix4::new( 91 | // 1.0, 0.0, 0.0, 0.0, 92 | // 0.0, 1.0, 0.0, 0.0, 93 | // 0.0, 0.0, 1.0, 0.0, 94 | // 0.0, 0.0, 0.0, 1.0 95 | // ).transpose() 96 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate cgmath; 2 | extern crate glium; 3 | 4 | // Re-export 5 | pub use pipeline::Pipeline; 6 | pub use camera::Camera; 7 | 8 | // Modules 9 | mod pipeline; 10 | mod graphical_math; 11 | mod camera; 12 | -------------------------------------------------------------------------------- /src/pipeline.rs: -------------------------------------------------------------------------------- 1 | 2 | use cgmath::{Vector3, Matrix, Matrix4}; 3 | use graphical_math; 4 | use graphical_math::PersProjInfo; 5 | 6 | fn default_matrix() -> Matrix4 { 7 | Matrix4::new( 8 | 1.0, 0.0, 0.0, 0.0, 9 | 0.0, 1.0, 0.0, 0.0, 10 | 0.0, 0.0, 1.0, 0.0, 11 | 0.0, 0.0, 0.0, 1.0 12 | ).transpose() 13 | } 14 | 15 | pub struct Pipeline { 16 | scale: Vector3, 17 | world_pos: Vector3, 18 | rotate_info: Vector3, 19 | 20 | pers_proj_info: PersProjInfo, 21 | camera_pos: Vector3, 22 | camera_target: Vector3, 23 | camera_up: Vector3, 24 | 25 | w_transformation: Matrix4, 26 | v_transformation: Matrix4, 27 | p_transformation: Matrix4, 28 | wp_transformation: Matrix4, 29 | wvp_transformation: Matrix4 30 | } 31 | 32 | impl Pipeline { 33 | pub fn new() -> Pipeline { 34 | Pipeline { 35 | scale: Vector3::new(1.0, 1.0, 1.0), 36 | world_pos: Vector3::new(0.0, 0.0, 0.0), 37 | rotate_info: Vector3::new(0.0, 0.0, 0.0), 38 | pers_proj_info: PersProjInfo::default(), 39 | camera_pos: Vector3::new(0.0, 0.0, 0.0), 40 | camera_target: Vector3::new(0.0, 0.0, 1.0), 41 | camera_up: Vector3::new(0.0, 1.0, 0.0), 42 | w_transformation: default_matrix(), 43 | v_transformation: default_matrix(), 44 | p_transformation: default_matrix(), 45 | wp_transformation: default_matrix(), 46 | wvp_transformation: default_matrix() 47 | } 48 | } 49 | 50 | pub fn scale(&mut self, scale_x: f32, scale_y: f32, scale_z: f32) { 51 | self.scale.x = scale_x; 52 | self.scale.y = scale_y; 53 | self.scale.z = scale_z; 54 | } 55 | 56 | pub fn world_pos(&mut self, x: f32, y: f32, z: f32) { 57 | self.world_pos.x = x; 58 | self.world_pos.y = y; 59 | self.world_pos.z = z; 60 | } 61 | 62 | pub fn rotate(&mut self, rotate_x: f32, rotate_y: f32, rotate_z: f32) { 63 | self.rotate_info.x = rotate_x; 64 | self.rotate_info.y = rotate_y; 65 | self.rotate_info.z = rotate_z; 66 | } 67 | 68 | pub fn set_perspective_proj(&mut self, fov: f32, width: f32, height: f32, z_near: f32, z_far: f32) { 69 | self.pers_proj_info = PersProjInfo { 70 | fov: fov, 71 | width: width, 72 | height: height, 73 | z_near: z_near, 74 | z_far: z_far 75 | }; 76 | } 77 | 78 | pub fn set_camera(&mut self, pos: Vector3, target: Vector3, up: Vector3) { 79 | self.camera_pos = pos; 80 | self.camera_target = target; 81 | self.camera_up = up; 82 | } 83 | 84 | pub fn get_world_trans(&mut self) -> Matrix4 { 85 | let scale_trans = graphical_math::init_scale_transform(self.scale.x, self.scale.y, self.scale.z); 86 | let rotate_trans = graphical_math::init_rotate_transform(self.rotate_info.x, self.rotate_info.y, self.rotate_info.z); 87 | let translation_trans = graphical_math::init_translation_transform(self.world_pos.x, self.world_pos.y, self.world_pos.z); 88 | 89 | self.w_transformation = translation_trans * rotate_trans * scale_trans; 90 | self.w_transformation 91 | } 92 | 93 | pub fn get_view_trans(&mut self) -> Matrix4 { 94 | let camera_translation_trans = graphical_math::init_translation_transform( 95 | -self.camera_pos.x, -self.camera_pos.y, -self.camera_pos.z); 96 | let camera_rotate_trans = graphical_math::init_camera_transform( 97 | self.camera_target, self.camera_up); 98 | 99 | self.v_transformation = camera_rotate_trans * camera_translation_trans; 100 | self.v_transformation 101 | } 102 | 103 | pub fn get_project_trans(&mut self) -> Matrix4 { 104 | self.p_transformation = graphical_math::init_pers_proj_transform(self.pers_proj_info); 105 | self.p_transformation 106 | } 107 | 108 | pub fn get_wp_trans(&mut self) -> Matrix4 { 109 | self.get_world_trans(); 110 | 111 | let pers_proj_trans = graphical_math::init_pers_proj_transform(self.pers_proj_info); 112 | 113 | self.wp_transformation = pers_proj_trans * self.w_transformation; 114 | self.wp_transformation 115 | } 116 | 117 | pub fn get_wvp_trans(&mut self) -> Matrix4 { 118 | self.get_world_trans(); 119 | self.get_view_trans(); 120 | self.get_project_trans(); 121 | 122 | self.wvp_transformation = self.p_transformation * self.v_transformation * self.w_transformation; 123 | self.wvp_transformation 124 | } 125 | } 126 | --------------------------------------------------------------------------------