├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── CODE_OF_CONDUCT.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── resources ├── fonts │ ├── Antonio-Bold.ttf │ ├── Antonio-Light.ttf │ ├── Antonio-Regular.ttf │ ├── OCRAEXT.TTF │ └── SIL Open Font License.txt ├── objects │ ├── backpack │ │ ├── ao.jpg │ │ ├── backpack.mtl │ │ ├── backpack.obj │ │ ├── diffuse.jpg │ │ ├── normal.png │ │ ├── roughness.jpg │ │ ├── source_attribution.txt │ │ └── specular.jpg │ ├── cube │ │ ├── cube.mtl │ │ ├── cube.obj │ │ └── cube.png │ ├── cyborg │ │ ├── LICENSE.txt │ │ ├── cyborg.blend │ │ ├── cyborg.blend1 │ │ ├── cyborg.mtl │ │ ├── cyborg.obj │ │ ├── cyborg_diffuse.png │ │ ├── cyborg_normal.png │ │ └── cyborg_specular.png │ ├── nanosuit │ │ ├── arm_dif.png │ │ ├── arm_showroom_ddn.png │ │ ├── arm_showroom_refl.png │ │ ├── arm_showroom_spec.png │ │ ├── back.jpg │ │ ├── body_dif.png │ │ ├── body_showroom_ddn.png │ │ ├── body_showroom_refl.png │ │ ├── body_showroom_spec.png │ │ ├── cell_arm_alpha.png │ │ ├── cell_body_alpha.png │ │ ├── cell_ddn.png │ │ ├── cell_hand_alpha.png │ │ ├── cell_helmet_alpha.png │ │ ├── cell_leg_alpha.png │ │ ├── front.jpg │ │ ├── glass_ddn.png │ │ ├── glass_dif.png │ │ ├── glass_refl.png │ │ ├── hand_dif.png │ │ ├── hand_showroom_ddn.png │ │ ├── hand_showroom_refl.png │ │ ├── hand_showroom_spec.png │ │ ├── helmet_diff.png │ │ ├── helmet_showroom_ddn.png │ │ ├── helmet_showroom_refl.png │ │ ├── helmet_showroom_spec.png │ │ ├── leg_dif.png │ │ ├── leg_showroom_ddn.png │ │ ├── leg_showroom_refl.png │ │ ├── leg_showroom_spec.png │ │ ├── nanosuit.mtl │ │ └── nanosuit.obj │ ├── planet │ │ ├── mars.png │ │ ├── planet.mtl │ │ ├── planet.obj │ │ ├── planet_Quom1200.png │ │ └── source.txt │ ├── rock │ │ ├── rock.mtl │ │ ├── rock.obj │ │ └── rock.png │ ├── spoon.mtl │ ├── spoon.obj │ ├── suzanne.obj │ ├── teacup.mtl │ ├── teacup.obj │ ├── teapot.mtl │ ├── teapot.obj │ └── vampire │ │ ├── dancing_vampire.dae │ │ └── textures │ │ ├── Vampire_diffuse.png │ │ ├── Vampire_emission.png │ │ ├── Vampire_normal.png │ │ └── Vampire_specular.png └── textures │ ├── awesomeface.png │ ├── brickwall.jpg │ ├── brickwall_normal.jpg │ ├── container.jpg │ ├── container2.png │ ├── container2_specular.png │ ├── grass.png │ ├── marble.jpg │ ├── metal.png │ ├── pbr │ └── rusted_iron │ │ ├── albedo.png │ │ ├── ao.png │ │ ├── metallic.png │ │ ├── normal.png │ │ └── roughness.png │ ├── skybox │ ├── back.jpg │ ├── bottom.jpg │ ├── front.jpg │ ├── left.jpg │ ├── right.jpg │ └── top.jpg │ ├── window.png │ └── wood.png └── src ├── _1_getting_started ├── README.md ├── _1_1_hello_window.rs ├── _1_2_hello_window_clear.rs ├── _2_1_hello_triangle.rs ├── _2_2_hello_triangle_indexed.rs ├── _2_3_hello_triangle_exercise1.rs ├── _2_4_hello_triangle_exercise2.rs ├── _2_5_hello_triangle_exercise3.rs ├── _3_1_shaders_uniform.rs ├── _3_2_shaders_interpolation.rs ├── _3_3_shaders_class.rs ├── _4_1_textures.rs ├── _4_2_textures_combined.rs ├── _5_1_transformations.rs ├── _6_1_coordinate_systems.rs ├── _6_2_coordinate_systems_depth.rs ├── _6_3_coordinate_systems_multiple.rs ├── _7_1_camera_circle.rs ├── _7_2_camera_keyboard_dt.rs ├── _7_3_camera_mouse_zoom.rs ├── _7_4_camera_class.rs ├── mod.rs └── shaders │ ├── 3.3.shader.fs │ ├── 3.3.shader.vs │ ├── 4.1.texture.fs │ ├── 4.1.texture.vs │ ├── 4.2.texture.fs │ ├── 4.2.texture.vs │ ├── 5.1.transform.fs │ ├── 5.1.transform.vs │ ├── 6.1.coordinate_systems.fs │ ├── 6.1.coordinate_systems.vs │ ├── 6.2.coordinate_systems.fs │ ├── 6.2.coordinate_systems.vs │ ├── 6.3.coordinate_systems.fs │ ├── 6.3.coordinate_systems.vs │ ├── 7.1.camera.fs │ ├── 7.1.camera.vs │ ├── 7.2.camera.fs │ ├── 7.2.camera.vs │ ├── 7.3.camera.fs │ ├── 7.3.camera.vs │ ├── 7.4.camera.fs │ └── 7.4.camera.vs ├── _2_lighting ├── README.md ├── _1_colors.rs ├── _2_1_basic_lighting_diffuse.rs ├── _2_2_basic_lighting_specular.rs ├── _3_1_materials.rs ├── _4_1_lighting_maps_diffuse_map.rs ├── _4_2_lighting_maps_specular_map.rs ├── _5_1_light_casters_directional.rs ├── _5_2_light_casters_point.rs ├── _5_3_light_casters_spot.rs ├── _5_4_light_casters_spot_soft.rs ├── _6_multiple_lights.rs ├── mod.rs └── shaders │ ├── 1.colors.fs │ ├── 1.colors.vs │ ├── 1.lamp.fs │ ├── 1.lamp.vs │ ├── 2.1.basic_lighting.fs │ ├── 2.1.basic_lighting.vs │ ├── 2.1.lamp.fs │ ├── 2.1.lamp.vs │ ├── 2.2.basic_lighting.fs │ ├── 2.2.basic_lighting.vs │ ├── 2.2.lamp.fs │ ├── 2.2.lamp.vs │ ├── 3.1.lamp.fs │ ├── 3.1.lamp.vs │ ├── 3.1.materials.fs │ ├── 3.1.materials.vs │ ├── 4.1.lamp.fs │ ├── 4.1.lamp.vs │ ├── 4.1.lighting_maps.fs │ ├── 4.1.lighting_maps.vs │ ├── 4.2.lamp.fs │ ├── 4.2.lamp.vs │ ├── 4.2.lighting_maps.fs │ ├── 4.2.lighting_maps.vs │ ├── 5.1.lamp.fs │ ├── 5.1.lamp.vs │ ├── 5.1.light_casters.fs │ ├── 5.1.light_casters.vs │ ├── 5.2.lamp.fs │ ├── 5.2.lamp.vs │ ├── 5.2.light_casters.fs │ ├── 5.2.light_casters.vs │ ├── 5.3.lamp.fs │ ├── 5.3.lamp.vs │ ├── 5.3.light_casters.fs │ ├── 5.3.light_casters.vs │ ├── 5.4.lamp.fs │ ├── 5.4.lamp.vs │ ├── 5.4.light_casters.fs │ ├── 5.4.light_casters.vs │ ├── 6.lamp.fs │ ├── 6.lamp.vs │ ├── 6.multiple_lights.fs │ └── 6.multiple_lights.vs ├── _3_model_loading ├── README.md ├── _1_model_loading.rs ├── mod.rs └── shaders │ ├── 1.model_loading.fs │ └── 1.model_loading.vs ├── _4_advanced_opengl ├── README.md ├── _1_1_depth_testing.rs ├── _1_2_depth_testing_view.rs ├── _2_stencil_testing.rs ├── _3_1_blending_discard.rs ├── _3_2_blending_sorted.rs ├── _5_1_framebuffers.rs ├── mod.rs └── shaders │ ├── 1.1.depth_testing.fs │ ├── 1.1.depth_testing.vs │ ├── 1.2.depth_testing.fs │ ├── 1.2.depth_testing.vs │ ├── 10.1.instancing.fs │ ├── 10.1.instancing.vs │ ├── 10.2.instancing.fs │ ├── 10.2.instancing.vs │ ├── 10.3.asteroids.fs │ ├── 10.3.asteroids.vs │ ├── 10.3.planet.fs │ ├── 10.3.planet.vs │ ├── 11.aa_post.fs │ ├── 11.aa_post.vs │ ├── 11.anti_aliasing.fs │ ├── 11.anti_aliasing.vs │ ├── 2.stencil_single_color.fs │ ├── 2.stencil_testing.fs │ ├── 2.stencil_testing.vs │ ├── 3.1.blending.fs │ ├── 3.1.blending.vs │ ├── 3.2.blending.fs │ ├── 3.2.blending.vs │ ├── 5.1.framebuffers.fs │ ├── 5.1.framebuffers.vs │ ├── 5.1.framebuffers_screen.fs │ ├── 5.1.framebuffers_screen.vs │ ├── 6.1.cubemaps.fs │ ├── 6.1.cubemaps.vs │ ├── 6.1.skybox.fs │ ├── 6.1.skybox.vs │ ├── 6.2.cubemaps.fs │ ├── 6.2.cubemaps.vs │ ├── 6.2.skybox.fs │ ├── 6.2.skybox.vs │ ├── 8.advanced_glsl.vs │ ├── 8.blue.fs │ ├── 8.green.fs │ ├── 8.red.fs │ ├── 8.yellow.fs │ ├── 9.1.geometry_shader.fs │ ├── 9.1.geometry_shader.gs │ ├── 9.1.geometry_shader.vs │ ├── 9.2.geometry_shader.fs │ ├── 9.2.geometry_shader.gs │ ├── 9.2.geometry_shader.vs │ ├── 9.3.default.fs │ ├── 9.3.default.vs │ ├── 9.3.normal_visualization.fs │ ├── 9.3.normal_visualization.gs │ └── 9.3.normal_visualization.vs ├── _7_in_practice ├── README.md ├── _1_debugging.rs ├── _2_text_rendering.rs ├── mod.rs └── shaders │ ├── debugging.fs │ ├── debugging.vs │ ├── text.fs │ └── text.vs ├── camera.rs ├── main.rs ├── mesh.rs ├── mesh_cube.rs ├── model.rs ├── shader.rs └── texture.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "cppvsdbg", 9 | "request": "launch", 10 | "name": "Debug", 11 | "program": "${workspaceFolder}/target/debug/lean-opengl-glow", 12 | "args": ["latest"], 13 | "cwd": "${workspaceFolder}" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "cargo run", 8 | "type": "shell", 9 | "command": "cargo", // note: full path to the cargo 10 | "args": [ 11 | "run", 12 | // "--release", 13 | // "--", 14 | "latest", 15 | ], 16 | "group": { 17 | "kind": "build", 18 | "isDefault": true 19 | } 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lean-opengl-glow" 3 | version = "0.1.0" 4 | authors = ["Albert Faber "] 5 | edition = "2021" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | glutin = "0.28" 11 | nalgebra-glm = "0.18" 12 | glow = { version = "0.12" } 13 | log = "0.4" 14 | anyhow = "1.0" 15 | thiserror = "1.0" 16 | bytemuck = "1.14" 17 | image = "0.24" 18 | tobj = "4.0" 19 | ab_glyph = "0.2" 20 | 21 | [features] 22 | default = [ 23 | "chapter-1", 24 | "chapter-2", 25 | "chapter-3", 26 | "chapter-4", 27 | #"chapter-5", 28 | #"chapter-6", 29 | "chapter-7", 30 | "chapter-8", 31 | ] 32 | chapter-1 = [] 33 | chapter-2 = [] 34 | chapter-3 = [] 35 | chapter-4 = [] 36 | chapter-5 = [] 37 | chapter-6 = [] 38 | chapter-7 = [] 39 | chapter-8 = [] 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 afaber999 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Rust port of https://github.com/JoeyDeVries/LearnOpenGL 3 | 4 | You should be able to follow the tutorials at https://learnopengl.com/ with this - the code structure has been kept similar to the original C++ but also tried to follow the rust style guidelines as much as possible. 5 | 6 | > However, it's not necessarily the most idiomatic Rust code.All OpenGL calls are only abstracted by glow and wrapped in `unsafe` blocks. 7 | If you want a rust implementation that will closer follow the C++ tutorial please see the [learn-opgenl-rs](https://github.com/bwasty/learn-opengl-rs) github repository. 8 | 9 | Run individual tutorials like this: 10 | `cargo run 1_3_2` (for `/src/_1_getting_started/_3_2_shaders_interpolation.rs`). 11 | 12 | For reduced compilation times, you may only compile the code for a certain chapter by adding `--no-default-features --features chapter-1` for example. 13 |

14 | 1_3_2 15 | 2_6 16 | 3_1 17 |

18 |

19 | 4_6_2 20 | 4_9_1 21 | 4_10_3 22 |

23 | 24 | ## Chapters 25 | ### [1. Getting started](src/_1_getting_started) 26 | **Notes** 27 | - You can mostly ignore the setup instructions at [Getting-started/Creating-a-window](https://learnopengl.com/#!Getting-started/Creating-a-window). Just create a new project with `cargo` and copy the dependency section from [Cargo.toml](Cargo.toml). The `glow` library is used to access the OpenGL API [(see details)](https://github.com/grovesNL/glow), in addition [glutin](https://github.com/tomaka/glutin) library is used to host the OpenGL application. 28 | - If you experience black screens or weird rendering artifacts, check out the [`glCheckError!`](https://github.com/bwasty/learn-opengl-rs/blob/89aed9919a2347e49965820830a6aecfdda18cf3/src/_7_in_practice/_1_debugging.rs#L28-L53) macro from chapter 7. 29 | - exercises have been mostly omitted. You can look up the solutions in the original C++ source (although it is still on my todo list). 30 | 31 | ### [2. Lighting](src/_2_lighting) 32 | ### [3. Model loading](src/_3_model_loading) 33 | **Notes** 34 | - For simplicity [`tobj`](https://github.com/Twinklebear/tobj) is used instead of `assimp` (simpler interface, pure Rust and later tutorials only load OBJ files anyway). For alternatives see [here](http://arewegameyet.com/categories/3dformatloader.html) and [here](https://crates.io/search?q=assimp). 35 | - The `image` crate is quite slow in debug mode - loading the nanosuit textures takes so much time that it can be faster to use release mode (including compile time). 36 | ### [4. Advanced OpenGL](src/_4_advanced_opengl) 37 | **Status:** in progress 38 | ### [5. Advanced Lighting](src/_5_advanced_lighting) 39 | **Status:** todo. 40 | ### [6. PBR](src/_6_pbr) 41 | **Status:** todo. 42 | ### [7. In Practice](src/_7_in_practice) 43 | **Status:** `Debugging` and 'text rendering' are in progress, the 2D breakout game will be in a seperate two repo) 44 | 45 | ---- 46 | ### A note about the code organization 47 | Now samples are intgrated in one big main which can lead to long compile times. As a workaround there is a config feature flags for each chapter. 48 | 49 | -------------------------------------------------------------------------------- /resources/fonts/Antonio-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/fonts/Antonio-Bold.ttf -------------------------------------------------------------------------------- /resources/fonts/Antonio-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/fonts/Antonio-Light.ttf -------------------------------------------------------------------------------- /resources/fonts/Antonio-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/fonts/Antonio-Regular.ttf -------------------------------------------------------------------------------- /resources/fonts/OCRAEXT.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/fonts/OCRAEXT.TTF -------------------------------------------------------------------------------- /resources/fonts/SIL Open Font License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-12, vernon adams (vern@newtypography.co.uk), with Reserved Font Names 'Antonio' 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 5 | 6 | ----------------------------------------------------------- 7 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 8 | ----------------------------------------------------------- 9 | 10 | PREAMBLE 11 | The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. 12 | 13 | The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. 14 | 15 | DEFINITIONS 16 | "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. 17 | 18 | "Reserved Font Name" refers to any names specified as such after the copyright statement(s). 19 | 20 | "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). 21 | 22 | "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. 23 | 24 | "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. 25 | 26 | PERMISSION & CONDITIONS 27 | Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 28 | 29 | 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 30 | 31 | 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 32 | 33 | 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 34 | 35 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 36 | 37 | 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. 38 | 39 | TERMINATION 40 | This license becomes null and void if any of the above conditions are not met. 41 | 42 | DISCLAIMER 43 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /resources/objects/backpack/ao.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/backpack/ao.jpg -------------------------------------------------------------------------------- /resources/objects/backpack/backpack.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Scene_-_Root 5 | Ns 225.000000 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.800000 0.800000 0.800000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.0 0.0 0.0 10 | Ni 1.450000 11 | d 1.000000 12 | illum 2 13 | map_Kd diffuse.jpg 14 | map_Bump normal.png 15 | map_Ks specular.jpg 16 | 17 | -------------------------------------------------------------------------------- /resources/objects/backpack/diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/backpack/diffuse.jpg -------------------------------------------------------------------------------- /resources/objects/backpack/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/backpack/normal.png -------------------------------------------------------------------------------- /resources/objects/backpack/roughness.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/backpack/roughness.jpg -------------------------------------------------------------------------------- /resources/objects/backpack/source_attribution.txt: -------------------------------------------------------------------------------- 1 | Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36 2 | 3 | Modified material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup. -------------------------------------------------------------------------------- /resources/objects/backpack/specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/backpack/specular.jpg -------------------------------------------------------------------------------- /resources/objects/cube/cube.mtl: -------------------------------------------------------------------------------- 1 | newmtl cube 2 | Ns 10.0000 3 | Ni 1.5000 4 | d 1.0000 5 | Tr 0.0000 6 | Tf 1.0000 1.0000 1.0000 7 | illum 2 8 | Ka 0.0000 0.0000 0.0000 9 | Kd 0.5880 0.5880 0.5880 10 | Ks 0.0000 0.0000 0.0000 11 | Ke 0.0000 0.0000 0.0000 12 | map_Ka cube.png 13 | map_Kd cube.png 14 | -------------------------------------------------------------------------------- /resources/objects/cube/cube.obj: -------------------------------------------------------------------------------- 1 | # cube.obj 2 | # 3 | 4 | o cube 5 | mtllib cube.mtl 6 | 7 | v -0.500000 -0.500000 0.500000 8 | v 0.500000 -0.500000 0.500000 9 | v -0.500000 0.500000 0.500000 10 | v 0.500000 0.500000 0.500000 11 | v -0.500000 0.500000 -0.500000 12 | v 0.500000 0.500000 -0.500000 13 | v -0.500000 -0.500000 -0.500000 14 | v 0.500000 -0.500000 -0.500000 15 | 16 | vt 0.000000 0.000000 17 | vt 1.000000 0.000000 18 | vt 0.000000 1.000000 19 | vt 1.000000 1.000000 20 | 21 | vn 0.000000 0.000000 1.000000 22 | vn 0.000000 1.000000 0.000000 23 | vn 0.000000 0.000000 -1.000000 24 | vn 0.000000 -1.000000 0.000000 25 | vn 1.000000 0.000000 0.000000 26 | vn -1.000000 0.000000 0.000000 27 | 28 | g cube 29 | usemtl cube 30 | s 1 31 | f 1/1/1 2/2/1 3/3/1 32 | f 3/3/1 2/2/1 4/4/1 33 | s 2 34 | f 3/1/2 4/2/2 5/3/2 35 | f 5/3/2 4/2/2 6/4/2 36 | s 3 37 | f 5/4/3 6/3/3 7/2/3 38 | f 7/2/3 6/3/3 8/1/3 39 | s 4 40 | f 7/1/4 8/2/4 1/3/4 41 | f 1/3/4 8/2/4 2/4/4 42 | s 5 43 | f 2/1/5 8/2/5 4/3/5 44 | f 4/3/5 8/2/5 6/4/5 45 | s 6 46 | f 7/1/6 1/2/6 5/3/6 47 | f 5/3/6 1/2/6 3/4/6 48 | -------------------------------------------------------------------------------- /resources/objects/cube/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/cube/cube.png -------------------------------------------------------------------------------- /resources/objects/cyborg/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Slightly adapted version (by Joey de Vries) of Cyborg model. 2 | 3 | From: 3dregenerator 4 | Downloaded at: http://tf3dm.com/3d-model/cyborg-78.html 5 | 6 | For Personal Use Only. -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/cyborg/cyborg.blend -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg.blend1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/cyborg/cyborg.blend1 -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'cyborg.blend' 2 | # Material Count: 1 3 | 4 | newmtl Cyborg 5 | Ns 92.156863 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.512000 0.512000 0.512000 8 | Ks 0.000000 0.000000 0.000000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | map_Kd cyborg_diffuse.png 13 | map_Bump cyborg_normal.png 14 | map_Ks cyborg_specular.png 15 | -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/cyborg/cyborg_diffuse.png -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/cyborg/cyborg_normal.png -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/cyborg/cyborg_specular.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/arm_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/arm_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/arm_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/arm_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/arm_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/arm_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/arm_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/arm_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/back.jpg -------------------------------------------------------------------------------- /resources/objects/nanosuit/body_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/body_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/body_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/body_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/body_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/body_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/body_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/body_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_arm_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/cell_arm_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_body_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/cell_body_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/cell_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_hand_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/cell_hand_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_helmet_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/cell_helmet_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_leg_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/cell_leg_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/front.jpg -------------------------------------------------------------------------------- /resources/objects/nanosuit/glass_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/glass_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/glass_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/glass_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/glass_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/glass_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/hand_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/hand_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/hand_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/hand_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/hand_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/hand_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/hand_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/hand_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/helmet_diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/helmet_diff.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/helmet_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/helmet_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/helmet_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/helmet_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/helmet_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/helmet_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/leg_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/leg_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/leg_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/leg_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/leg_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/leg_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/leg_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/nanosuit/leg_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/nanosuit.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'nanosuit.blend' 2 | # Material Count: 6 3 | 4 | newmtl Arm 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.500000 0.500000 0.500000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | map_Bump arm_showroom_ddn.png 13 | map_Ka arm_showroom_refl.png 14 | map_Kd arm_dif.png 15 | map_Ks arm_showroom_spec.png 16 | 17 | newmtl Body 18 | Ns 96.078431 19 | Ka 0.000000 0.000000 0.000000 20 | Kd 0.640000 0.640000 0.640000 21 | Ks 0.500000 0.500000 0.500000 22 | Ni 1.000000 23 | d 1.000000 24 | illum 2 25 | map_Kd body_dif.png 26 | map_Bump body_showroom_ddn.png 27 | map_Ka body_showroom_refl.png 28 | map_Ks body_showroom_spec.png 29 | 30 | newmtl Glass 31 | Ns 96.078431 32 | Ka 0.000000 0.000000 0.000000 33 | Kd 0.640000 0.640000 0.640000 34 | Ks 0.500000 0.500000 0.500000 35 | Ni 1.000000 36 | d 1.000000 37 | illum 2 38 | map_Bump glass_ddn.png 39 | map_Ka glass_refl.png 40 | map_Kd glass_dif.png 41 | 42 | newmtl Hand 43 | Ns 96.078431 44 | Ka 0.000000 0.000000 0.000000 45 | Kd 0.640000 0.640000 0.640000 46 | Ks 0.500000 0.500000 0.500000 47 | Ni 1.000000 48 | d 1.000000 49 | illum 2 50 | map_Bump hand_showroom_ddn.png 51 | map_Ka hand_showroom_refl.png 52 | map_Kd hand_dif.png 53 | map_Ks hand_showroom_spec.png 54 | 55 | newmtl Helmet 56 | Ns 96.078431 57 | Ka 0.000000 0.000000 0.000000 58 | Kd 0.640000 0.640000 0.640000 59 | Ks 0.500000 0.500000 0.500000 60 | Ni 1.000000 61 | d 1.000000 62 | illum 2 63 | map_Bump helmet_showroom_ddn.png 64 | map_Ka helmet_showroom_refl.png 65 | map_Kd helmet_diff.png 66 | map_Ks helmet_showroom_spec.png 67 | 68 | newmtl Leg 69 | Ns 96.078431 70 | Ka 0.000000 0.000000 0.000000 71 | Kd 0.640000 0.640000 0.640000 72 | Ks 0.500000 0.500000 0.500000 73 | Ni 1.000000 74 | d 1.000000 75 | illum 2 76 | map_Bump leg_showroom_ddn.png 77 | map_Ka leg_showroom_refl.png 78 | map_Kd leg_dif.png 79 | map_Ks leg_showroom_spec.png 80 | -------------------------------------------------------------------------------- /resources/objects/planet/mars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/planet/mars.png -------------------------------------------------------------------------------- /resources/objects/planet/planet.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Mars 5 | Ns 96.078443 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.0 0.0 0.0 10 | Ni 1.000000 11 | d 1.000000 12 | illum 2 13 | map_Kd mars.png 14 | -------------------------------------------------------------------------------- /resources/objects/planet/planet_Quom1200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/planet/planet_Quom1200.png -------------------------------------------------------------------------------- /resources/objects/planet/source.txt: -------------------------------------------------------------------------------- 1 | From TurboSquid, by Gerhald3D: https://www.turbosquid.com/3d-models/realistic-mars-photorealistic-2k-3d-1277433 2 | Slightly modified by Joey de Vries: keep only planet layer, assign diffuse texture to material slot, desaturated texture somewhat. -------------------------------------------------------------------------------- /resources/objects/rock/rock.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'Rock1.blend' 2 | # Material Count: 1 3 | 4 | newmtl Material 5 | Ns 13.725490 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.007937 0.007937 0.007937 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | map_Bump rock.png 13 | -------------------------------------------------------------------------------- /resources/objects/rock/rock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/rock/rock.png -------------------------------------------------------------------------------- /resources/objects/spoon.mtl: -------------------------------------------------------------------------------- 1 | newmtl FrontColor 2 | Ka 0.000000 0.000000 0.000000 3 | Kd 1.000000 1.000000 1.000000 4 | Ks 0.330000 0.330000 0.330000 -------------------------------------------------------------------------------- /resources/objects/teacup.mtl: -------------------------------------------------------------------------------- 1 | newmtl FrontColor 2 | Ka 0.000000 0.000000 0.000000 3 | Kd 1.000000 1.000000 1.000000 4 | Ks 0.330000 0.330000 0.330000 5 | -------------------------------------------------------------------------------- /resources/objects/teapot.mtl: -------------------------------------------------------------------------------- 1 | newmtl FrontColor 2 | Ka 0.000000 0.000000 0.000000 3 | Kd 1.000000 1.000000 1.000000 4 | Ks 0.330000 0.330000 0.330000 5 | -------------------------------------------------------------------------------- /resources/objects/vampire/textures/Vampire_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/vampire/textures/Vampire_diffuse.png -------------------------------------------------------------------------------- /resources/objects/vampire/textures/Vampire_emission.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/vampire/textures/Vampire_emission.png -------------------------------------------------------------------------------- /resources/objects/vampire/textures/Vampire_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/vampire/textures/Vampire_normal.png -------------------------------------------------------------------------------- /resources/objects/vampire/textures/Vampire_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/objects/vampire/textures/Vampire_specular.png -------------------------------------------------------------------------------- /resources/textures/awesomeface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/awesomeface.png -------------------------------------------------------------------------------- /resources/textures/brickwall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/brickwall.jpg -------------------------------------------------------------------------------- /resources/textures/brickwall_normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/brickwall_normal.jpg -------------------------------------------------------------------------------- /resources/textures/container.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/container.jpg -------------------------------------------------------------------------------- /resources/textures/container2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/container2.png -------------------------------------------------------------------------------- /resources/textures/container2_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/container2_specular.png -------------------------------------------------------------------------------- /resources/textures/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/grass.png -------------------------------------------------------------------------------- /resources/textures/marble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/marble.jpg -------------------------------------------------------------------------------- /resources/textures/metal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/metal.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/albedo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/pbr/rusted_iron/albedo.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/ao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/pbr/rusted_iron/ao.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/metallic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/pbr/rusted_iron/metallic.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/pbr/rusted_iron/normal.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/roughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/pbr/rusted_iron/roughness.png -------------------------------------------------------------------------------- /resources/textures/skybox/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/skybox/back.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/skybox/bottom.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/skybox/front.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/left.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/skybox/left.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/right.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/skybox/right.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/skybox/top.jpg -------------------------------------------------------------------------------- /resources/textures/window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/window.png -------------------------------------------------------------------------------- /resources/textures/wood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afaber999/rust_learn_opengl_glow/543a0212fdd5e7017c871da8569c0f659c0c3cf5/resources/textures/wood.png -------------------------------------------------------------------------------- /src/_1_getting_started/README.md: -------------------------------------------------------------------------------- 1 | ### Tutorials 2 | [OpenGL](https://learnopengl.com/#!Getting-started/OpenGL)
3 | [Creating-a-window](https://learnopengl.com/#!Getting-started/Creating-a-window)
4 | [Hello-Window](https://learnopengl.com/#!Getting-started/Hello-Window)
5 | [Hello-Triangle](https://learnopengl.com/#!Getting-started/Hello-Triangle) 6 | [Shaders](https://learnopengl.com/#!Getting-started/Shaders)
7 | * see also [`../shader.rs`](../shader.rs) 8 | 9 | [Textures](https://learnopengl.com/#!Getting-started/Textures)
10 | [Transformations](https://learnopengl.com/#!Getting-started/Transformations)
11 | [Coordinate-Systems](https://learnopengl.com/#!Getting-started/Coordinate-Systems)
12 | [Camera](https://learnopengl.com/#!Getting-started/Camera)
13 | * see also [`../camera.rs`](../camera.rs) 14 | 15 | [Review](https://learnopengl.com/#!Getting-started/Review) 16 | -------------------------------------------------------------------------------- /src/_1_getting_started/_1_1_hello_window.rs: -------------------------------------------------------------------------------- 1 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 2 | use glutin::event_loop::ControlFlow; 3 | 4 | const SCR_WIDTH: u32 = 800; 5 | const SCR_HEIGHT: u32 = 600; 6 | 7 | pub fn main_1_1_1() { 8 | 9 | unsafe 10 | { 11 | let event_loop = glutin::event_loop::EventLoop::new(); 12 | let window_builder = glutin::window::WindowBuilder::new() 13 | .with_title("learn-opengl-glow => _1_1_hello_window") 14 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 15 | let window = glutin::ContextBuilder::new() 16 | .with_vsync(true) 17 | .build_windowed(window_builder, &event_loop) 18 | .unwrap() 19 | .make_current() 20 | .unwrap(); 21 | 22 | event_loop.run(move |event, _, control_flow| { 23 | 24 | *control_flow = ControlFlow::WaitUntil( std::time::Instant::now() + std::time::Duration::from_millis(16)); 25 | 26 | match event { 27 | Event::LoopDestroyed => { return;} 28 | Event::RedrawRequested(_) => { 29 | // DRAW HERE 30 | window.swap_buffers().unwrap(); 31 | }, 32 | 33 | Event::WindowEvent { ref event, .. } => match event { 34 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 35 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 36 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 37 | match input.virtual_keycode { 38 | Some(key) if key == VirtualKeyCode::Escape => { 39 | *control_flow = glutin::event_loop::ControlFlow::Exit; 40 | }, 41 | _ => (), 42 | } 43 | }, 44 | _=> {} 45 | }, 46 | _ => {} 47 | } 48 | } ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/_1_getting_started/_1_2_hello_window_clear.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 3 | use glutin::event_loop::ControlFlow; 4 | 5 | const SCR_WIDTH: u32 = 800; 6 | const SCR_HEIGHT: u32 = 600; 7 | 8 | pub fn main_1_1_2() { 9 | 10 | unsafe 11 | { 12 | let event_loop = glutin::event_loop::EventLoop::new(); 13 | let window_builder = glutin::window::WindowBuilder::new() 14 | .with_title("learn-opengl-glow => _1_2_hello_window_clear") 15 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 16 | let window = glutin::ContextBuilder::new() 17 | .with_vsync(true) 18 | .build_windowed(window_builder, &event_loop) 19 | .unwrap() 20 | .make_current() 21 | .unwrap(); 22 | let gl=glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); 23 | 24 | event_loop.run(move |event, _, control_flow| { 25 | 26 | *control_flow = ControlFlow::WaitUntil( std::time::Instant::now() + std::time::Duration::from_millis(16)); 27 | 28 | match event { 29 | Event::LoopDestroyed => { return;} 30 | Event::RedrawRequested(_) => { 31 | // DRAW HERE 32 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 33 | gl.clear(glow::COLOR_BUFFER_BIT); 34 | 35 | window.swap_buffers().unwrap(); 36 | }, 37 | 38 | Event::WindowEvent { ref event, .. } => match event { 39 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 40 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 41 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 42 | match input.virtual_keycode { 43 | Some(key) if key == VirtualKeyCode::Escape => { 44 | *control_flow = glutin::event_loop::ControlFlow::Exit; 45 | }, 46 | _ => (), 47 | } 48 | }, 49 | _=> {} 50 | }, 51 | _ => {} 52 | } 53 | } ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/_1_getting_started/_2_1_hello_triangle.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 3 | use glutin::event_loop::ControlFlow; 4 | 5 | const SCR_WIDTH: u32 = 800; 6 | const SCR_HEIGHT: u32 = 600; 7 | 8 | pub fn main_1_2_1() { 9 | 10 | unsafe 11 | { 12 | let event_loop = glutin::event_loop::EventLoop::new(); 13 | let window_builder = glutin::window::WindowBuilder::new() 14 | .with_title("learn-opengl-glow => _2_1_hello_triangle") 15 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 16 | let window = glutin::ContextBuilder::new() 17 | .with_vsync(true) 18 | .build_windowed(window_builder, &event_loop) 19 | .unwrap() 20 | .make_current() 21 | .unwrap(); 22 | let gl=glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); 23 | 24 | let vx_source = r#" 25 | #version 330 core 26 | layout (location = 0) in vec3 aPos; 27 | void main() { 28 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 29 | } 30 | "#; 31 | 32 | let fg_source = r#" 33 | #version 330 core 34 | out vec4 FragColor; 35 | void main() { 36 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 37 | } 38 | "#; 39 | 40 | // build and compile our shader program 41 | // ------------------------------------ 42 | // vertex shader 43 | let program = gl.create_program().expect("Cannot create program"); 44 | 45 | let vx_shader = gl 46 | .create_shader(glow::VERTEX_SHADER) 47 | .expect(&format!( "Cannot create shader: {}", glow::VERTEX_SHADER)); 48 | 49 | gl.shader_source(vx_shader, vx_source); 50 | gl.compile_shader(vx_shader); 51 | 52 | // check for shader compile errors 53 | if !gl.get_shader_compile_status(vx_shader) { 54 | panic!( "{}", gl.get_shader_info_log(vx_shader)); 55 | } 56 | gl.attach_shader(program, vx_shader); 57 | 58 | // fragment shader 59 | let fg_shader = gl 60 | .create_shader(glow::FRAGMENT_SHADER) 61 | .expect(&format!( "Cannot create shader: {}", glow::FRAGMENT_SHADER)); 62 | 63 | gl.shader_source(fg_shader, fg_source); 64 | gl.compile_shader(fg_shader); 65 | 66 | // check for shader compile errors 67 | if !gl.get_shader_compile_status(fg_shader) { 68 | panic!( "{}", gl.get_shader_info_log(fg_shader)); 69 | } 70 | gl.attach_shader(program, fg_shader); 71 | 72 | // link shaders and check result 73 | gl.link_program(program); 74 | if !gl.get_program_link_status(program) { 75 | panic!( "{}", gl.get_program_info_log(program)); 76 | } 77 | 78 | gl.detach_shader(program, vx_shader); 79 | gl.delete_shader(vx_shader); 80 | 81 | gl.detach_shader(program, fg_shader); 82 | gl.delete_shader(fg_shader); 83 | 84 | // set up vertex data (and buffer(s)) and configure vertex attributes 85 | // ------------------------------------------------------------------ 86 | // HINT: type annotation is crucial since default for float literals is f64 87 | let vertices: [f32; 9] = [ 88 | -0.5, -0.5, 0.0, // left 89 | 0.5, -0.5, 0.0, // right 90 | 0.0, 0.5, 0.0 // top 91 | ]; 92 | 93 | let vao = gl.create_vertex_array().expect("Create VAO"); 94 | let vbo = gl.create_buffer().expect("Create VBO"); 95 | 96 | // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). 97 | gl.bind_vertex_array( Some(vao) ); 98 | 99 | gl.bind_buffer(glow::ARRAY_BUFFER, Some( vbo )); 100 | let u8_buffer = bytemuck::cast_slice(&vertices[..]); 101 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 102 | 103 | gl.vertex_attrib_pointer_f32( 104 | 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 105 | 3, // 3 elements 106 | glow::FLOAT, 107 | false, 108 | 0, 109 | 0 ); 110 | 111 | gl.enable_vertex_attrib_array(0); 112 | 113 | // note that this is allowed, the call to glVertexAttribPointer registered VBO as the 114 | // vertex attribute's bound vertex buffer object so afterwards we can safely unbind 115 | gl.bind_buffer(glow::ARRAY_BUFFER, None); 116 | 117 | // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, 118 | // but this rarely happens. Modifying other VAOs requires a call to glBindVertexArray 119 | // anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. 120 | gl.bind_vertex_array(None); 121 | 122 | // uncomment this call to draw in wireframe polygons. 123 | // gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); 124 | 125 | event_loop.run(move |event, _, control_flow| { 126 | 127 | *control_flow = ControlFlow::WaitUntil( std::time::Instant::now() + std::time::Duration::from_millis(16)); 128 | 129 | match event { 130 | Event::RedrawRequested(_) => { 131 | // DRAW HERE 132 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 133 | gl.clear(glow::COLOR_BUFFER_BIT); 134 | 135 | // draw our first triangle 136 | gl.use_program(Some(program)); 137 | 138 | gl.bind_vertex_array(Some(vao)); 139 | gl.draw_arrays(glow::TRIANGLES, 0, 3); 140 | 141 | // no need to unbind it every time 142 | gl.bind_vertex_array(None); 143 | 144 | window.swap_buffers().unwrap(); 145 | }, 146 | 147 | Event::WindowEvent { ref event, .. } => match event { 148 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 149 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 150 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 151 | match input.virtual_keycode { 152 | Some(key) if key == VirtualKeyCode::Escape => { 153 | *control_flow = glutin::event_loop::ControlFlow::Exit; 154 | }, 155 | _ => (), 156 | } 157 | }, 158 | _=> {} 159 | }, 160 | 161 | Event::LoopDestroyed => { 162 | // CLEANUP 163 | gl.delete_buffer(vbo); 164 | gl.delete_vertex_array(vao); 165 | gl.delete_program(program); 166 | }, 167 | _ => {} 168 | } 169 | } ); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/_1_getting_started/_2_2_hello_triangle_indexed.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 3 | use glutin::event_loop::ControlFlow; 4 | 5 | const SCR_WIDTH: u32 = 800; 6 | const SCR_HEIGHT: u32 = 600; 7 | 8 | pub fn main_1_2_2() { 9 | 10 | unsafe 11 | { 12 | let event_loop = glutin::event_loop::EventLoop::new(); 13 | let window_builder = glutin::window::WindowBuilder::new() 14 | .with_title("learn-opengl-glow => _2_2_hello_triangle_indexed") 15 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 16 | let window = glutin::ContextBuilder::new() 17 | .with_vsync(true) 18 | .build_windowed(window_builder, &event_loop) 19 | .unwrap() 20 | .make_current() 21 | .unwrap(); 22 | let gl=glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); 23 | 24 | let vx_source = r#" 25 | #version 330 core 26 | layout (location = 0) in vec3 aPos; 27 | void main() { 28 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 29 | } 30 | "#; 31 | 32 | let fg_source = r#" 33 | #version 330 core 34 | out vec4 FragColor; 35 | void main() { 36 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 37 | } 38 | "#; 39 | 40 | // build and compile our shader program 41 | // ------------------------------------ 42 | // vertex shader 43 | let program = gl.create_program().expect("Cannot create program"); 44 | 45 | let vx_shader = gl 46 | .create_shader(glow::VERTEX_SHADER) 47 | .expect(&format!( "Cannot create shader: {}", glow::VERTEX_SHADER)); 48 | 49 | gl.shader_source(vx_shader, vx_source); 50 | gl.compile_shader(vx_shader); 51 | 52 | // check for shader compile errors 53 | if !gl.get_shader_compile_status(vx_shader) { 54 | panic!( "{}", gl.get_shader_info_log(vx_shader)); 55 | } 56 | gl.attach_shader(program, vx_shader); 57 | 58 | // fragment shader 59 | let fg_shader = gl 60 | .create_shader(glow::FRAGMENT_SHADER) 61 | .expect(&format!( "Cannot create shader: {}", glow::FRAGMENT_SHADER)); 62 | 63 | gl.shader_source(fg_shader, fg_source); 64 | gl.compile_shader(fg_shader); 65 | 66 | // check for shader compile errors 67 | if !gl.get_shader_compile_status(fg_shader) { 68 | panic!( "{}", gl.get_shader_info_log(fg_shader)); 69 | } 70 | gl.attach_shader(program, fg_shader); 71 | 72 | // link shaders and check result 73 | gl.link_program(program); 74 | if !gl.get_program_link_status(program) { 75 | panic!( "{}", gl.get_program_info_log(program)); 76 | } 77 | 78 | gl.detach_shader(program, vx_shader); 79 | gl.delete_shader(vx_shader); 80 | 81 | gl.detach_shader(program, fg_shader); 82 | gl.delete_shader(fg_shader); 83 | 84 | // set up vertex data (and buffer(s)) and configure vertex attributes 85 | // ------------------------------------------------------------------ 86 | // HINT: type annotation is crucial since default for float literals is f64 87 | let vertices:[f32;12] = [ 88 | 0.5, 0.5, 0.0, // top right 89 | 0.5, -0.5, 0.0, // bottom right 90 | -0.5, -0.5, 0.0, // bottom left 91 | -0.5, 0.5, 0.0 // top left 92 | ]; 93 | 94 | let indices = [ // note that we start from 0! 95 | 0, 1, 3, // first Triangle 96 | 1, 2, 3 // second Triangle 97 | ]; 98 | 99 | let vao = gl.create_vertex_array().expect("Create VAO"); 100 | let vbo = gl.create_buffer().expect("Create VBO"); 101 | let ebo = gl.create_buffer().expect("Create EBO"); 102 | 103 | // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). 104 | gl.bind_vertex_array( Some(vao) ); 105 | 106 | gl.bind_buffer(glow::ARRAY_BUFFER, Some( vbo )); 107 | let u8_buffer = bytemuck::cast_slice(&vertices[..]); 108 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 109 | 110 | gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ebo)); 111 | let u8_buffer = bytemuck::cast_slice(&indices[..]); 112 | gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 113 | 114 | gl.vertex_attrib_pointer_f32( 115 | 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 116 | 3, // 3 elements 117 | glow::FLOAT, 118 | false, 119 | 0, 120 | 0 ); 121 | 122 | gl.enable_vertex_attrib_array(0); 123 | 124 | // note that this is allowed, the call to glVertexAttribPointer registered VBO as the 125 | // vertex attribute's bound vertex buffer object so afterwards we can safely unbind 126 | gl.bind_buffer(glow::ARRAY_BUFFER, None); 127 | 128 | // remember: do NOT unbind the EBO while a VAO is active as the bound 129 | // element buffer object IS stored in the VAO; keep the EBO bound. 130 | //self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None); 131 | 132 | // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, 133 | // but this rarely happens. Modifying other VAOs requires a call to glBindVertexArray 134 | // anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. 135 | gl.bind_vertex_array(None); 136 | 137 | // uncomment this call to draw in wireframe polygons. 138 | // gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); 139 | 140 | event_loop.run(move |event, _, control_flow| { 141 | 142 | *control_flow = ControlFlow::WaitUntil( std::time::Instant::now() + std::time::Duration::from_millis(16)); 143 | 144 | match event { 145 | Event::RedrawRequested(_) => { 146 | // DRAW HERE 147 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 148 | gl.clear(glow::COLOR_BUFFER_BIT); 149 | 150 | // draw our first triangle 151 | gl.use_program(Some(program)); 152 | 153 | // seeing as we only have a single VAO there's no need to bind it every time, 154 | // but we'll do so to keep things a bit more organized 155 | gl.bind_vertex_array(Some(vao)); 156 | gl.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_INT,0); 157 | 158 | // no need to unbind it every time 159 | gl.bind_vertex_array(None); 160 | 161 | window.swap_buffers().unwrap(); 162 | }, 163 | 164 | Event::WindowEvent { ref event, .. } => match event { 165 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 166 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 167 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 168 | match input.virtual_keycode { 169 | Some(key) if key == VirtualKeyCode::Escape => { 170 | *control_flow = glutin::event_loop::ControlFlow::Exit; 171 | }, 172 | _ => (), 173 | } 174 | }, 175 | _=> {} 176 | }, 177 | 178 | Event::LoopDestroyed => { 179 | // CLEANUP 180 | gl.delete_buffer(ebo); 181 | gl.delete_buffer(vbo); 182 | gl.delete_vertex_array(vao); 183 | gl.delete_program(program); 184 | }, 185 | _ => {} 186 | } 187 | } ); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/_1_getting_started/_2_3_hello_triangle_exercise1.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 3 | use glutin::event_loop::ControlFlow; 4 | 5 | const SCR_WIDTH: u32 = 800; 6 | const SCR_HEIGHT: u32 = 600; 7 | 8 | pub fn main_1_2_3() { 9 | 10 | unsafe 11 | { 12 | let event_loop = glutin::event_loop::EventLoop::new(); 13 | let window_builder = glutin::window::WindowBuilder::new() 14 | .with_title("learn-opengl-glow => _2_3_hello_triangle_exercise1") 15 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 16 | let window = glutin::ContextBuilder::new() 17 | .with_vsync(true) 18 | .build_windowed(window_builder, &event_loop) 19 | .unwrap() 20 | .make_current() 21 | .unwrap(); 22 | let gl=glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); 23 | 24 | let vx_source = r#" 25 | #version 330 core 26 | layout (location = 0) in vec3 aPos; 27 | void main() { 28 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 29 | } 30 | "#; 31 | 32 | let fg_source = r#" 33 | #version 330 core 34 | out vec4 FragColor; 35 | void main() { 36 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 37 | } 38 | "#; 39 | 40 | // build and compile our shader program 41 | // ------------------------------------ 42 | // vertex shader 43 | let program = gl.create_program().expect("Cannot create program"); 44 | 45 | let vx_shader = gl 46 | .create_shader(glow::VERTEX_SHADER) 47 | .expect(&format!( "Cannot create shader: {}", glow::VERTEX_SHADER)); 48 | 49 | gl.shader_source(vx_shader, vx_source); 50 | gl.compile_shader(vx_shader); 51 | 52 | // check for shader compile errors 53 | if !gl.get_shader_compile_status(vx_shader) { 54 | panic!( "{}", gl.get_shader_info_log(vx_shader)); 55 | } 56 | gl.attach_shader(program, vx_shader); 57 | 58 | // fragment shader 59 | let fg_shader = gl 60 | .create_shader(glow::FRAGMENT_SHADER) 61 | .expect(&format!( "Cannot create shader: {}", glow::FRAGMENT_SHADER)); 62 | 63 | gl.shader_source(fg_shader, fg_source); 64 | gl.compile_shader(fg_shader); 65 | 66 | // check for shader compile errors 67 | if !gl.get_shader_compile_status(fg_shader) { 68 | panic!( "{}", gl.get_shader_info_log(fg_shader)); 69 | } 70 | gl.attach_shader(program, fg_shader); 71 | 72 | // link shaders and check result 73 | gl.link_program(program); 74 | if !gl.get_program_link_status(program) { 75 | panic!( "{}", gl.get_program_info_log(program)); 76 | } 77 | 78 | gl.detach_shader(program, vx_shader); 79 | gl.delete_shader(vx_shader); 80 | 81 | gl.detach_shader(program, fg_shader); 82 | gl.delete_shader(fg_shader); 83 | 84 | // set up vertex data (and buffer(s)) and configure vertex attributes 85 | // ------------------------------------------------------------------ 86 | // add a new set of vertices to form a second triangle (a total of 6 vertices); 87 | // the vertex attribute configuration remains the same (still one 3-float position vector per vertex) 88 | let vertices:[f32;18] = [ 89 | // first triangle 90 | -0.9, -0.5, 0.0, // left 91 | -0.0, -0.5, 0.0, // right 92 | -0.45, 0.5, 0.0, // top 93 | // second triangle 94 | 0.0, -0.5, 0.0, // left 95 | 0.9, -0.5, 0.0, // right 96 | 0.45, 0.5, 0.0 // top 97 | ]; 98 | 99 | let vao = gl.create_vertex_array().expect("Create VAO"); 100 | let vbo = gl.create_buffer().expect("Create VBO"); 101 | 102 | // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). 103 | gl.bind_vertex_array( Some(vao) ); 104 | 105 | gl.bind_buffer(glow::ARRAY_BUFFER, Some( vbo )); 106 | let u8_buffer = bytemuck::cast_slice(&vertices[..]); 107 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 108 | 109 | gl.vertex_attrib_pointer_f32( 110 | 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 111 | 3, // 3 elements 112 | glow::FLOAT, 113 | false, 114 | 0, 115 | 0 ); 116 | 117 | gl.enable_vertex_attrib_array(0); 118 | 119 | // note that this is allowed, the call to glVertexAttribPointer registered VBO as the 120 | // vertex attribute's bound vertex buffer object so afterwards we can safely unbind 121 | gl.bind_buffer(glow::ARRAY_BUFFER, None); 122 | 123 | // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, 124 | // but this rarely happens. Modifying other VAOs requires a call to glBindVertexArray 125 | // anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. 126 | gl.bind_vertex_array(None); 127 | 128 | // uncomment this call to draw in wireframe polygons. 129 | // gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); 130 | 131 | event_loop.run(move |event, _, control_flow| { 132 | 133 | *control_flow = ControlFlow::WaitUntil( std::time::Instant::now() + std::time::Duration::from_millis(16)); 134 | 135 | match event { 136 | Event::RedrawRequested(_) => { 137 | // DRAW HERE 138 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 139 | gl.clear(glow::COLOR_BUFFER_BIT); 140 | 141 | // draw our first triangle 142 | gl.use_program(Some(program)); 143 | 144 | // seeing as we only have a single VAO there's no need to bind it every time, 145 | // but we'll do so to keep things a bit more organized 146 | gl.bind_vertex_array(Some(vao)); 147 | 148 | // set the count to 6 since we're drawing 6 vertices now (2 triangles); not 3! 149 | gl.draw_arrays(glow::TRIANGLES, 0,6); 150 | 151 | // no need to unbind it every time 152 | gl.bind_vertex_array(None); 153 | 154 | window.swap_buffers().unwrap(); 155 | }, 156 | 157 | Event::WindowEvent { ref event, .. } => match event { 158 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 159 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 160 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 161 | match input.virtual_keycode { 162 | Some(key) if key == VirtualKeyCode::Escape => { 163 | *control_flow = glutin::event_loop::ControlFlow::Exit; 164 | }, 165 | _ => (), 166 | } 167 | }, 168 | _=> {} 169 | }, 170 | 171 | Event::LoopDestroyed => { 172 | // CLEANUP 173 | gl.delete_buffer(vbo); 174 | gl.delete_vertex_array(vao); 175 | gl.delete_program(program); 176 | }, 177 | _ => {} 178 | } 179 | } ); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/_1_getting_started/_2_4_hello_triangle_exercise2.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 3 | use glutin::event_loop::ControlFlow; 4 | 5 | const SCR_WIDTH: u32 = 800; 6 | const SCR_HEIGHT: u32 = 600; 7 | 8 | pub fn main_1_2_4() { 9 | 10 | unsafe 11 | { 12 | let event_loop = glutin::event_loop::EventLoop::new(); 13 | let window_builder = glutin::window::WindowBuilder::new() 14 | .with_title("learn-opengl-glow => _2_4_hello_triangle_exercise2") 15 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 16 | let window = glutin::ContextBuilder::new() 17 | .with_vsync(true) 18 | .build_windowed(window_builder, &event_loop) 19 | .unwrap() 20 | .make_current() 21 | .unwrap(); 22 | let gl=glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); 23 | 24 | let vx_source = r#" 25 | #version 330 core 26 | layout (location = 0) in vec3 aPos; 27 | void main() { 28 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 29 | } 30 | "#; 31 | 32 | let fg_source = r#" 33 | #version 330 core 34 | out vec4 FragColor; 35 | void main() { 36 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 37 | } 38 | "#; 39 | 40 | // build and compile our shader program 41 | // ------------------------------------ 42 | // vertex shader 43 | let program = gl.create_program().expect("Cannot create program"); 44 | 45 | let vx_shader = gl 46 | .create_shader(glow::VERTEX_SHADER) 47 | .expect(&format!( "Cannot create shader: {}", glow::VERTEX_SHADER)); 48 | 49 | gl.shader_source(vx_shader, vx_source); 50 | gl.compile_shader(vx_shader); 51 | 52 | // check for shader compile errors 53 | if !gl.get_shader_compile_status(vx_shader) { 54 | panic!( "{}", gl.get_shader_info_log(vx_shader)); 55 | } 56 | gl.attach_shader(program, vx_shader); 57 | 58 | // fragment shader 59 | let fg_shader = gl 60 | .create_shader(glow::FRAGMENT_SHADER) 61 | .expect(&format!( "Cannot create shader: {}", glow::FRAGMENT_SHADER)); 62 | 63 | gl.shader_source(fg_shader, fg_source); 64 | gl.compile_shader(fg_shader); 65 | 66 | // check for shader compile errors 67 | if !gl.get_shader_compile_status(fg_shader) { 68 | panic!( "{}", gl.get_shader_info_log(fg_shader)); 69 | } 70 | gl.attach_shader(program, fg_shader); 71 | 72 | // link shaders and check result 73 | gl.link_program(program); 74 | if !gl.get_program_link_status(program) { 75 | panic!( "{}", gl.get_program_info_log(program)); 76 | } 77 | 78 | gl.detach_shader(program, vx_shader); 79 | gl.delete_shader(vx_shader); 80 | 81 | gl.detach_shader(program, fg_shader); 82 | gl.delete_shader(fg_shader); 83 | 84 | // set up vertex data (and buffer(s)) and configure vertex attributes 85 | // ------------------------------------------------------------------ 86 | let first_triangle:[f32;9] = [ 87 | -0.9, -0.5, 0.0, // left 88 | -0.0, -0.5, 0.0, // right 89 | -0.45, 0.5, 0.0, // top 90 | ]; 91 | let second_triangle:[f32;9] = [ 92 | 0.0, -0.5, 0.0, // left 93 | 0.9, -0.5, 0.0, // right 94 | 0.45, 0.5, 0.0 // top 95 | ]; 96 | 97 | let vao1 = gl.create_vertex_array().expect("Create VAO1"); 98 | let vao2 = gl.create_vertex_array().expect("Create VAO2"); 99 | let vbo1 = gl.create_buffer().expect("Create VBO 1"); 100 | let vbo2 = gl.create_buffer().expect("Create VBO 2"); 101 | 102 | // first triangle setup 103 | // --------------------- 104 | gl.bind_vertex_array( Some(vao1) ); 105 | gl.bind_buffer(glow::ARRAY_BUFFER, Some( vbo1 )); 106 | let u8_buffer = bytemuck::cast_slice(&first_triangle[..]); 107 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 108 | 109 | gl.vertex_attrib_pointer_f32( 110 | 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 111 | 3, // 3 elements 112 | glow::FLOAT, 113 | false, 114 | 0, 115 | 0 ); 116 | 117 | gl.enable_vertex_attrib_array(0); 118 | 119 | // second triangle setup 120 | // --------------------- 121 | gl.bind_vertex_array( Some(vao2) ); 122 | gl.bind_buffer(glow::ARRAY_BUFFER, Some( vbo2 )); 123 | let u8_buffer = bytemuck::cast_slice(&second_triangle[..]); 124 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 125 | 126 | gl.vertex_attrib_pointer_f32( 127 | 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 128 | 3, // 3 elements 129 | glow::FLOAT, 130 | false, 131 | 0, 132 | 0 ); 133 | 134 | gl.enable_vertex_attrib_array(0); 135 | 136 | // not really necessary as well, but beware of calls that could affect VAOs while this one is bound 137 | // (like binding element buffer objects, or enabling/disabling vertex attributes) 138 | gl.bind_vertex_array(None); 139 | 140 | // uncomment this call to draw in wireframe polygons. 141 | // gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); 142 | 143 | event_loop.run(move |event, _, control_flow| { 144 | 145 | *control_flow = ControlFlow::WaitUntil( std::time::Instant::now() + std::time::Duration::from_millis(16)); 146 | 147 | match event { 148 | Event::RedrawRequested(_) => { 149 | // DRAW HERE 150 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 151 | gl.clear(glow::COLOR_BUFFER_BIT); 152 | 153 | gl.use_program(Some(program)); 154 | 155 | // draw first triangle 156 | gl.bind_vertex_array(Some(vao1)); 157 | gl.draw_arrays(glow::TRIANGLES, 0,3); 158 | 159 | // draw first triangle 160 | gl.bind_vertex_array(Some(vao2)); 161 | gl.draw_arrays(glow::TRIANGLES, 0,3); 162 | 163 | window.swap_buffers().unwrap(); 164 | }, 165 | 166 | Event::WindowEvent { ref event, .. } => match event { 167 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 168 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 169 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 170 | match input.virtual_keycode { 171 | Some(key) if key == VirtualKeyCode::Escape => { 172 | *control_flow = glutin::event_loop::ControlFlow::Exit; 173 | }, 174 | _ => (), 175 | } 176 | }, 177 | _=> {} 178 | }, 179 | 180 | Event::LoopDestroyed => { 181 | // CLEANUP 182 | gl.delete_buffer(vbo1); 183 | gl.delete_buffer(vbo2); 184 | gl.delete_vertex_array(vao1); 185 | gl.delete_vertex_array(vao2); 186 | gl.delete_program(program); 187 | }, 188 | _ => {} 189 | } 190 | } ); 191 | } 192 | } 193 | 194 | -------------------------------------------------------------------------------- /src/_1_getting_started/_3_1_shaders_uniform.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 3 | use glutin::event_loop::ControlFlow; 4 | 5 | const SCR_WIDTH: u32 = 800; 6 | const SCR_HEIGHT: u32 = 600; 7 | 8 | pub fn main_1_3_1() { 9 | 10 | unsafe 11 | { 12 | let event_loop = glutin::event_loop::EventLoop::new(); 13 | let window_builder = glutin::window::WindowBuilder::new() 14 | .with_title("learn-opengl-glow => _3_1_shaders_uniform") 15 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 16 | let window = glutin::ContextBuilder::new() 17 | .with_vsync(true) 18 | .build_windowed(window_builder, &event_loop) 19 | .unwrap() 20 | .make_current() 21 | .unwrap(); 22 | let gl=glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); 23 | 24 | let vx_source = r#" 25 | #version 330 core 26 | layout (location = 0) in vec3 aPos; 27 | void main() { 28 | gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); 29 | } 30 | "#; 31 | 32 | let fg_source = r#" 33 | #version 330 core 34 | out vec4 FragColor; 35 | uniform vec4 ourColor; 36 | void main() { 37 | FragColor = ourColor; 38 | } 39 | "#; 40 | 41 | // build and compile our shader program 42 | // ------------------------------------ 43 | // vertex shader 44 | let program = gl.create_program().expect("Cannot create program"); 45 | 46 | let vx_shader = gl 47 | .create_shader(glow::VERTEX_SHADER) 48 | .expect(&format!( "Cannot create shader: {}", glow::VERTEX_SHADER)); 49 | 50 | gl.shader_source(vx_shader, vx_source); 51 | gl.compile_shader(vx_shader); 52 | 53 | // check for shader compile errors 54 | if !gl.get_shader_compile_status(vx_shader) { 55 | panic!( "{}", gl.get_shader_info_log(vx_shader)); 56 | } 57 | gl.attach_shader(program, vx_shader); 58 | 59 | // fragment shader 60 | let fg_shader = gl 61 | .create_shader(glow::FRAGMENT_SHADER) 62 | .expect(&format!( "Cannot create shader: {}", glow::FRAGMENT_SHADER)); 63 | 64 | gl.shader_source(fg_shader, fg_source); 65 | gl.compile_shader(fg_shader); 66 | 67 | // check for shader compile errors 68 | if !gl.get_shader_compile_status(fg_shader) { 69 | panic!( "{}", gl.get_shader_info_log(fg_shader)); 70 | } 71 | gl.attach_shader(program, fg_shader); 72 | 73 | // link shaders and check result 74 | gl.link_program(program); 75 | if !gl.get_program_link_status(program) { 76 | panic!( "{}", gl.get_program_info_log(program)); 77 | } 78 | 79 | gl.detach_shader(program, vx_shader); 80 | gl.delete_shader(vx_shader); 81 | 82 | gl.detach_shader(program, fg_shader); 83 | gl.delete_shader(fg_shader); 84 | 85 | // set up vertex data (and buffer(s)) and configure vertex attributes 86 | // ------------------------------------------------------------------ 87 | // HINT: type annotation is crucial since default for float literals is f64 88 | let vertices: [f32; 9] = [ 89 | -0.5, -0.5, 0.0, // left 90 | 0.5, -0.5, 0.0, // right 91 | 0.0, 0.5, 0.0 // top 92 | ]; 93 | 94 | let vao = gl.create_vertex_array().expect("Create VAO"); 95 | let vbo = gl.create_buffer().expect("Create VBO"); 96 | 97 | // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). 98 | gl.bind_vertex_array( Some(vao) ); 99 | 100 | gl.bind_buffer(glow::ARRAY_BUFFER, Some( vbo )); 101 | let u8_buffer = bytemuck::cast_slice(&vertices[..]); 102 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 103 | 104 | gl.vertex_attrib_pointer_f32( 105 | 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 106 | 3, // 3 elements 107 | glow::FLOAT, 108 | false, 109 | 0, 110 | 0 ); 111 | 112 | gl.enable_vertex_attrib_array(0); 113 | 114 | // note that this is allowed, the call to glVertexAttribPointer registered VBO as the 115 | // vertex attribute's bound vertex buffer object so afterwards we can safely unbind 116 | gl.bind_buffer(glow::ARRAY_BUFFER, None); 117 | 118 | // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, 119 | // but this rarely happens. Modifying other VAOs requires a call to glBindVertexArray 120 | // anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. 121 | gl.bind_vertex_array(None); 122 | 123 | // uncomment this call to draw in wireframe polygons. 124 | // gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); 125 | const DESIRED_FRAME_TIME :f32 = 0.02; 126 | let mut last_draw_time = std::time::Instant::now(); 127 | let mut frame_time= 0.0f32; 128 | 129 | event_loop.run(move |event, _, control_flow| { 130 | 131 | let now = std::time::Instant::now(); 132 | let elapsed_time = now.duration_since(last_draw_time).as_secs_f32(); 133 | 134 | if elapsed_time > DESIRED_FRAME_TIME { 135 | frame_time += elapsed_time; 136 | window.window().request_redraw(); 137 | last_draw_time = now; 138 | } 139 | 140 | match event { 141 | Event::RedrawRequested(_) => { 142 | // DRAW HERE 143 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 144 | gl.clear(glow::COLOR_BUFFER_BIT); 145 | 146 | // be sure to activate the shader before any calls to glUniform 147 | gl.use_program(Some(program)); 148 | 149 | let green_value = ((frame_time ).sin() / 2.0) + 0.5; 150 | let our_color = gl.get_uniform_location(program, "ourColor"); 151 | gl.uniform_4_f32(our_color.as_ref(), 0.0, green_value, 0.0, 0.0); 152 | 153 | gl.bind_vertex_array(Some(vao)); 154 | gl.draw_arrays(glow::TRIANGLES, 0, 3); 155 | 156 | // no need to unbind it every time 157 | gl.bind_vertex_array(None); 158 | 159 | window.swap_buffers().unwrap(); 160 | }, 161 | 162 | Event::WindowEvent { ref event, .. } => match event { 163 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 164 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 165 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 166 | match input.virtual_keycode { 167 | Some(key) if key == VirtualKeyCode::Escape => { 168 | *control_flow = glutin::event_loop::ControlFlow::Exit; 169 | }, 170 | _ => (), 171 | } 172 | }, 173 | _=> {} 174 | }, 175 | 176 | Event::LoopDestroyed => { 177 | // CLEANUP 178 | gl.delete_buffer(vbo); 179 | gl.delete_vertex_array(vao); 180 | gl.delete_program(program); 181 | }, 182 | _ => {} 183 | } 184 | } ); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/_1_getting_started/_3_2_shaders_interpolation.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 3 | use glutin::event_loop::ControlFlow; 4 | 5 | const SCR_WIDTH: u32 = 800; 6 | const SCR_HEIGHT: u32 = 600; 7 | 8 | pub fn main_1_3_2() { 9 | 10 | unsafe 11 | { 12 | let event_loop = glutin::event_loop::EventLoop::new(); 13 | let window_builder = glutin::window::WindowBuilder::new() 14 | .with_title("learn-opengl-glow => _3_2_shaders_interpolation") 15 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 16 | let window = glutin::ContextBuilder::new() 17 | .with_vsync(true) 18 | .build_windowed(window_builder, &event_loop) 19 | .unwrap() 20 | .make_current() 21 | .unwrap(); 22 | let gl=glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _); 23 | 24 | let vx_source = r#" 25 | #version 330 core 26 | layout (location = 0) in vec3 aPos; 27 | layout (location = 1) in vec3 aColor; 28 | out vec3 ourColor; 29 | void main() { 30 | gl_Position = vec4(aPos, 1.0); 31 | ourColor = aColor; 32 | } 33 | "#; 34 | 35 | let fg_source = r#" 36 | #version 330 core 37 | out vec4 FragColor; 38 | in vec3 ourColor; 39 | void main() { 40 | FragColor = vec4(ourColor, 1.0f); 41 | } 42 | "#; 43 | 44 | // build and compile our shader program 45 | // ------------------------------------ 46 | // vertex shader 47 | let program = gl.create_program().expect("Cannot create program"); 48 | 49 | let vx_shader = gl 50 | .create_shader(glow::VERTEX_SHADER) 51 | .expect(&format!( "Cannot create shader: {}", glow::VERTEX_SHADER)); 52 | 53 | gl.shader_source(vx_shader, vx_source); 54 | gl.compile_shader(vx_shader); 55 | 56 | // check for shader compile errors 57 | if !gl.get_shader_compile_status(vx_shader) { 58 | panic!( "{}", gl.get_shader_info_log(vx_shader)); 59 | } 60 | gl.attach_shader(program, vx_shader); 61 | 62 | // fragment shader 63 | let fg_shader = gl 64 | .create_shader(glow::FRAGMENT_SHADER) 65 | .expect(&format!( "Cannot create shader: {}", glow::FRAGMENT_SHADER)); 66 | 67 | gl.shader_source(fg_shader, fg_source); 68 | gl.compile_shader(fg_shader); 69 | 70 | // check for shader compile errors 71 | if !gl.get_shader_compile_status(fg_shader) { 72 | panic!( "{}", gl.get_shader_info_log(fg_shader)); 73 | } 74 | gl.attach_shader(program, fg_shader); 75 | 76 | // link shaders and check result 77 | gl.link_program(program); 78 | if !gl.get_program_link_status(program) { 79 | panic!( "{}", gl.get_program_info_log(program)); 80 | } 81 | 82 | gl.detach_shader(program, vx_shader); 83 | gl.delete_shader(vx_shader); 84 | 85 | gl.detach_shader(program, fg_shader); 86 | gl.delete_shader(fg_shader); 87 | 88 | // set up vertex data (and buffer(s)) and configure vertex attributes 89 | // ------------------------------------------------------------------ 90 | // HINT: type annotation is crucial since default for float literals is f64 91 | let vertices: [f32; 18] = [ 92 | // positions // colors 93 | 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, // bottom right 94 | -0.5, -0.5, 0.0, 0.0, 1.0, 0.0, // bottom left 95 | 0.0, 0.5, 0.0, 0.0, 0.0, 1.0 // top 96 | ]; 97 | 98 | let vao = gl.create_vertex_array().expect("Create VAO"); 99 | let vbo = gl.create_buffer().expect("Create VBO"); 100 | 101 | // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). 102 | gl.bind_vertex_array( Some(vao) ); 103 | 104 | gl.bind_buffer(glow::ARRAY_BUFFER, Some( vbo )); 105 | let u8_buffer = bytemuck::cast_slice(&vertices[..]); 106 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 107 | 108 | // Vertex position attribute 0. No particular reason for 0, but must match the layout in the shader. 109 | gl.vertex_attrib_pointer_f32( 110 | 0, 111 | 3, // 3 elements 112 | glow::FLOAT, 113 | false, 114 | std::mem::size_of::() as i32 * 6, 115 | 0); 116 | 117 | gl.enable_vertex_attrib_array(0); 118 | 119 | // Color attribute 1. No particular reason for 1, but must match the layout in the shader. 120 | gl.vertex_attrib_pointer_f32( 121 | 1, 122 | 3, // 3 elements 123 | glow::FLOAT, 124 | false, 125 | std::mem::size_of::() as i32 * 6, 126 | std::mem::size_of::() as i32 * 3); 127 | 128 | gl.enable_vertex_attrib_array(1); 129 | 130 | // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, 131 | // but this rarely happens. Modifying other VAOs requires a call to glBindVertexArray 132 | // anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. 133 | // gl.bind_vertex_array(Some(0)); 134 | 135 | // uncomment this call to draw in wireframe polygons. 136 | // gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); 137 | const DESIRED_FRAME_TIME :f32 = 0.02; 138 | let mut last_draw_time = std::time::Instant::now(); 139 | 140 | event_loop.run(move |event, _, control_flow| { 141 | 142 | let now = std::time::Instant::now(); 143 | let elapsed_time = now.duration_since(last_draw_time).as_secs_f32(); 144 | 145 | if elapsed_time > DESIRED_FRAME_TIME { 146 | window.window().request_redraw(); 147 | last_draw_time = now; 148 | } 149 | 150 | match event { 151 | Event::RedrawRequested(_) => { 152 | // DRAW HERE 153 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 154 | gl.clear(glow::COLOR_BUFFER_BIT); 155 | 156 | gl.use_program(Some(program)); 157 | gl.bind_vertex_array(Some(vao)); 158 | gl.draw_arrays(glow::TRIANGLES, 0, 3); 159 | 160 | window.swap_buffers().unwrap(); 161 | }, 162 | 163 | Event::WindowEvent { ref event, .. } => match event { 164 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 165 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 166 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 167 | match input.virtual_keycode { 168 | Some(key) if key == VirtualKeyCode::Escape => { 169 | *control_flow = glutin::event_loop::ControlFlow::Exit; 170 | }, 171 | _ => (), 172 | } 173 | }, 174 | _=> {} 175 | }, 176 | 177 | Event::LoopDestroyed => { 178 | // CLEANUP 179 | gl.delete_buffer(vbo); 180 | gl.delete_vertex_array(vao); 181 | gl.delete_program(program); 182 | }, 183 | _ => {} 184 | } 185 | } ); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/_1_getting_started/_3_3_shaders_class.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent}; 3 | use glutin::event_loop::ControlFlow; 4 | use std::rc::Rc; 5 | use crate::shader::Shader; 6 | 7 | const SCR_WIDTH: u32 = 800; 8 | const SCR_HEIGHT: u32 = 600; 9 | 10 | pub fn main_1_3_3() { 11 | 12 | unsafe 13 | { 14 | let event_loop = glutin::event_loop::EventLoop::new(); 15 | let window_builder = glutin::window::WindowBuilder::new() 16 | .with_title("learn-opengl-glow => _3_2_shaders_interpolation") 17 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 18 | let window = glutin::ContextBuilder::new() 19 | .with_vsync(true) 20 | .build_windowed(window_builder, &event_loop) 21 | .unwrap() 22 | .make_current() 23 | .unwrap(); 24 | let gl=Rc::new(glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _)); 25 | 26 | 27 | let shader = Shader::new_from_files( 28 | gl.clone(), 29 | "src/_1_getting_started/shaders/3.3.shader.vs", 30 | "src/_1_getting_started/shaders/3.3.shader.fs" 31 | ); 32 | 33 | // set up vertex data (and buffer(s)) and configure vertex attributes 34 | // ------------------------------------------------------------------ 35 | // HINT: type annotation is crucial since default for float literals is f64 36 | let vertices: [f32; 18] = [ 37 | // positions // colors 38 | 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, // bottom right 39 | -0.5, -0.5, 0.0, 0.0, 1.0, 0.0, // bottom left 40 | 0.0, 0.5, 0.0, 0.0, 0.0, 1.0 // top 41 | ]; 42 | 43 | let vao = gl.create_vertex_array().expect("Create VAO"); 44 | let vbo = gl.create_buffer().expect("Create VBO"); 45 | 46 | // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). 47 | gl.bind_vertex_array( Some(vao) ); 48 | 49 | gl.bind_buffer(glow::ARRAY_BUFFER, Some( vbo )); 50 | let u8_buffer = bytemuck::cast_slice(&vertices[..]); 51 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 52 | 53 | // Vertex position attribute 0. No particular reason for 0, but must match the layout in the shader. 54 | gl.vertex_attrib_pointer_f32( 55 | 0, 56 | 3, // 3 elements 57 | glow::FLOAT, 58 | false, 59 | std::mem::size_of::() as i32 * 6, 60 | 0); 61 | 62 | gl.enable_vertex_attrib_array(0); 63 | 64 | // Color attribute 1. No particular reason for 1, but must match the layout in the shader. 65 | gl.vertex_attrib_pointer_f32( 66 | 1, 67 | 3, // 3 elements 68 | glow::FLOAT, 69 | false, 70 | std::mem::size_of::() as i32 * 6, 71 | std::mem::size_of::() as i32 * 3); 72 | 73 | gl.enable_vertex_attrib_array(1); 74 | 75 | // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, 76 | // but this rarely happens. Modifying other VAOs requires a call to glBindVertexArray 77 | // anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. 78 | // gl.bind_vertex_array(Some(0)); 79 | 80 | // uncomment this call to draw in wireframe polygons. 81 | // gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); 82 | const DESIRED_FRAME_TIME :f32 = 0.02; 83 | let mut last_draw_time = std::time::Instant::now(); 84 | 85 | event_loop.run(move |event, _, control_flow| { 86 | 87 | let now = std::time::Instant::now(); 88 | let elapsed_time = now.duration_since(last_draw_time).as_secs_f32(); 89 | 90 | if elapsed_time > DESIRED_FRAME_TIME { 91 | window.window().request_redraw(); 92 | last_draw_time = now; 93 | } 94 | 95 | match event { 96 | Event::RedrawRequested(_) => { 97 | // DRAW HERE 98 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 99 | gl.clear(glow::COLOR_BUFFER_BIT); 100 | 101 | shader.use_program(); 102 | 103 | gl.bind_vertex_array(Some(vao)); 104 | gl.draw_arrays(glow::TRIANGLES, 0, 3); 105 | 106 | window.swap_buffers().unwrap(); 107 | }, 108 | 109 | Event::WindowEvent { ref event, .. } => match event { 110 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 111 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 112 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 113 | match input.virtual_keycode { 114 | Some(key) if key == VirtualKeyCode::Escape => { 115 | *control_flow = glutin::event_loop::ControlFlow::Exit; 116 | }, 117 | _ => (), 118 | } 119 | }, 120 | _=> {} 121 | }, 122 | 123 | Event::LoopDestroyed => { 124 | // CLEANUP 125 | gl.delete_buffer(vbo); 126 | gl.delete_vertex_array(vao); 127 | }, 128 | _ => {} 129 | } 130 | } ); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/_1_getting_started/mod.rs: -------------------------------------------------------------------------------- 1 | mod _1_1_hello_window; 2 | pub use self::_1_1_hello_window::*; 3 | mod _1_2_hello_window_clear; 4 | pub use self::_1_2_hello_window_clear::*; 5 | mod _2_1_hello_triangle; 6 | pub use self::_2_1_hello_triangle::*; 7 | mod _2_2_hello_triangle_indexed; 8 | pub use self::_2_2_hello_triangle_indexed::*; 9 | mod _2_3_hello_triangle_exercise1; 10 | pub use self::_2_3_hello_triangle_exercise1::*; 11 | mod _2_4_hello_triangle_exercise2; 12 | pub use self::_2_4_hello_triangle_exercise2::*; 13 | mod _2_5_hello_triangle_exercise3; 14 | pub use self::_2_5_hello_triangle_exercise3::*; 15 | mod _3_1_shaders_uniform; 16 | pub use self::_3_1_shaders_uniform::*; 17 | mod _3_2_shaders_interpolation; 18 | pub use self::_3_2_shaders_interpolation::*; 19 | mod _3_3_shaders_class; 20 | pub use self::_3_3_shaders_class::*; 21 | mod _4_1_textures; 22 | pub use self::_4_1_textures::*; 23 | mod _4_2_textures_combined; 24 | pub use self::_4_2_textures_combined::*; 25 | mod _5_1_transformations; 26 | pub use self::_5_1_transformations::*; 27 | mod _6_1_coordinate_systems; 28 | pub use self::_6_1_coordinate_systems::*; 29 | mod _6_2_coordinate_systems_depth; 30 | pub use self::_6_2_coordinate_systems_depth::*; 31 | mod _6_3_coordinate_systems_multiple; 32 | pub use self::_6_3_coordinate_systems_multiple::*; 33 | mod _7_1_camera_circle; 34 | pub use self::_7_1_camera_circle::*; 35 | mod _7_2_camera_keyboard_dt; 36 | pub use self::_7_2_camera_keyboard_dt::*; 37 | mod _7_3_camera_mouse_zoom; 38 | pub use self::_7_3_camera_mouse_zoom::*; 39 | mod _7_4_camera_class; 40 | pub use self::_7_4_camera_class::*; 41 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/3.3.shader.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 ourColor; 5 | 6 | void main() 7 | { 8 | FragColor = vec4(ourColor, 1.0f); 9 | } 10 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/3.3.shader.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aColor; 4 | 5 | out vec3 ourColor; 6 | 7 | void main() 8 | { 9 | gl_Position = vec4(aPos, 1.0); 10 | ourColor = aColor; 11 | } 12 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/4.1.texture.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 ourColor; 5 | in vec2 TexCoord; 6 | 7 | // texture sampler 8 | uniform sampler2D texture1; 9 | 10 | void main() 11 | { 12 | FragColor = texture(texture1, TexCoord); 13 | } 14 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/4.1.texture.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aColor; 4 | layout (location = 2) in vec2 aTexCoord; 5 | 6 | out vec3 ourColor; 7 | out vec2 TexCoord; 8 | 9 | void main() 10 | { 11 | gl_Position = vec4(aPos, 1.0); 12 | ourColor = aColor; 13 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/4.2.texture.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 ourColor; 5 | in vec2 TexCoord; 6 | 7 | // texture samplers 8 | uniform sampler2D texture1; 9 | uniform sampler2D texture2; 10 | 11 | void main() 12 | { 13 | // linearly interpolate between both textures (80% container, 20% awesomeface) 14 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 15 | } 16 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/4.2.texture.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aColor; 4 | layout (location = 2) in vec2 aTexCoord; 5 | 6 | out vec3 ourColor; 7 | out vec2 TexCoord; 8 | 9 | void main() 10 | { 11 | gl_Position = vec4(aPos, 1.0); 12 | ourColor = aColor; 13 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/5.1.transform.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoord; 5 | 6 | // texture samplers 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() 11 | { 12 | // linearly interpolate between both textures (80% container, 20% awesomeface) 13 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/5.1.transform.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 transform; 8 | 9 | void main() 10 | { 11 | gl_Position = transform * vec4(aPos, 1.0); 12 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 13 | } 14 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/6.1.coordinate_systems.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoord; 5 | 6 | // texture samplers 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() 11 | { 12 | // linearly interpolate between both textures (80% container, 20% awesomeface) 13 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/6.1.coordinate_systems.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0); 14 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 15 | } -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/6.2.coordinate_systems.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoord; 5 | 6 | // texture samplers 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() 11 | { 12 | // linearly interpolate between both textures (80% container, 20% awesomeface) 13 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/6.2.coordinate_systems.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 14 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 15 | } 16 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/6.3.coordinate_systems.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoord; 5 | 6 | uniform sampler2D texture1; 7 | uniform sampler2D texture2; 8 | 9 | void main() 10 | { 11 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 12 | } 13 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/6.3.coordinate_systems.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 14 | TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y); 15 | } 16 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/7.1.camera.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoord; 5 | 6 | // texture samplers 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() 11 | { 12 | // linearly interpolate between both textures (80% container, 20% awesomeface) 13 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/7.1.camera.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 14 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 15 | } 16 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/7.2.camera.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoord; 5 | 6 | // texture samplers 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() 11 | { 12 | // linearly interpolate between both textures (80% container, 20% awesomeface) 13 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/7.2.camera.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 14 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 15 | } 16 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/7.3.camera.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoord; 5 | 6 | // texture samplers 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() 11 | { 12 | // linearly interpolate between both textures (80% container, 20% awesomeface) 13 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/7.3.camera.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 14 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 15 | } 16 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/7.4.camera.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoord; 5 | 6 | // texture samplers 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() 11 | { 12 | // linearly interpolate between both textures (80% container, 20% awesomeface) 13 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 14 | } 15 | -------------------------------------------------------------------------------- /src/_1_getting_started/shaders/7.4.camera.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoord; 4 | 5 | out vec2 TexCoord; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 14 | TexCoord = vec2(aTexCoord.x, aTexCoord.y); 15 | } 16 | -------------------------------------------------------------------------------- /src/_2_lighting/README.md: -------------------------------------------------------------------------------- 1 | 2 | ### Tutorials 3 | [Colors](https://learnopengl.com/#!Lighting/Colors)
4 | [Basic-Lighting](https://learnopengl.com/#!Lighting/Basic-Lighting)
5 | [Materials](https://learnopengl.com/#!Lighting/Materials)
6 | [Lighting-maps](https://learnopengl.com/#!Lighting/Lighting-maps)
7 | [Light-casters](https://learnopengl.com/#!Lighting/Light-casters)
8 | [Multiple-lights](https://learnopengl.com/#!Lighting/Multiple-lights)
9 | [Review](https://learnopengl.com/#!Lighting/Review)
10 | -------------------------------------------------------------------------------- /src/_2_lighting/mod.rs: -------------------------------------------------------------------------------- 1 | mod _1_colors; 2 | pub use self::_1_colors::*; 3 | mod _2_1_basic_lighting_diffuse; 4 | pub use self::_2_1_basic_lighting_diffuse::*; 5 | mod _2_2_basic_lighting_specular; 6 | pub use self::_2_2_basic_lighting_specular::*; 7 | mod _3_1_materials; 8 | pub use self::_3_1_materials::*; 9 | mod _4_1_lighting_maps_diffuse_map; 10 | pub use self::_4_1_lighting_maps_diffuse_map::*; 11 | mod _4_2_lighting_maps_specular_map; 12 | pub use self::_4_2_lighting_maps_specular_map::*; 13 | mod _5_1_light_casters_directional; 14 | pub use self::_5_1_light_casters_directional::*; 15 | mod _5_2_light_casters_point; 16 | pub use self::_5_2_light_casters_point::*; 17 | mod _5_3_light_casters_spot; 18 | pub use self::_5_3_light_casters_spot::*; 19 | mod _5_4_light_casters_spot_soft; 20 | pub use self::_5_4_light_casters_spot_soft::*; 21 | // mod _6_multiple_lights; 22 | // pub use self::_6_multiple_lights::*; 23 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/1.colors.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | uniform vec3 objectColor; 5 | uniform vec3 lightColor; 6 | 7 | void main() 8 | { 9 | FragColor = vec4(lightColor * objectColor, 1.0); 10 | } 11 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/1.colors.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/1.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/1.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/2.1.basic_lighting.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 Normal; 5 | in vec3 FragPos; 6 | 7 | uniform vec3 lightPos; 8 | uniform vec3 lightColor; 9 | uniform vec3 objectColor; 10 | 11 | void main() 12 | { 13 | // ambient 14 | float ambientStrength = 0.1; 15 | vec3 ambient = ambientStrength * lightColor; 16 | 17 | // diffuse 18 | vec3 norm = normalize(Normal); 19 | vec3 lightDir = normalize(lightPos - FragPos); 20 | float diff = max(dot(norm, lightDir), 0.0); 21 | vec3 diffuse = diff * lightColor; 22 | 23 | vec3 result = (ambient + diffuse) * objectColor; 24 | FragColor = vec4(result, 1.0); 25 | } 26 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/2.1.basic_lighting.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | 5 | out vec3 FragPos; 6 | out vec3 Normal; 7 | 8 | uniform mat4 model; 9 | uniform mat4 view; 10 | uniform mat4 projection; 11 | 12 | void main() 13 | { 14 | FragPos = vec3(model * vec4(aPos, 1.0)); 15 | Normal = aNormal; 16 | 17 | gl_Position = projection * view * vec4(FragPos, 1.0); 18 | } 19 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/2.1.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/2.1.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/2.2.basic_lighting.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 Normal; 5 | in vec3 FragPos; 6 | 7 | uniform vec3 lightPos; 8 | uniform vec3 viewPos; 9 | uniform vec3 lightColor; 10 | uniform vec3 objectColor; 11 | 12 | void main() 13 | { 14 | // ambient 15 | float ambientStrength = 0.1; 16 | vec3 ambient = ambientStrength * lightColor; 17 | 18 | // diffuse 19 | vec3 norm = normalize(Normal); 20 | vec3 lightDir = normalize(lightPos - FragPos); 21 | float diff = max(dot(norm, lightDir), 0.0); 22 | vec3 diffuse = diff * lightColor; 23 | 24 | // specular 25 | float specularStrength = 0.5; 26 | vec3 viewDir = normalize(viewPos - FragPos); 27 | vec3 reflectDir = reflect(-lightDir, norm); 28 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 29 | vec3 specular = specularStrength * spec * lightColor; 30 | 31 | vec3 result = (ambient + diffuse + specular) * objectColor; 32 | FragColor = vec4(result, 1.0); 33 | } 34 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/2.2.basic_lighting.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | 5 | out vec3 FragPos; 6 | out vec3 Normal; 7 | 8 | uniform mat4 model; 9 | uniform mat4 view; 10 | uniform mat4 projection; 11 | 12 | void main() 13 | { 14 | FragPos = vec3(model * vec4(aPos, 1.0)); 15 | Normal = mat3(transpose(inverse(model))) * aNormal; 16 | 17 | gl_Position = projection * view * vec4(FragPos, 1.0); 18 | } 19 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/2.2.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/2.2.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/3.1.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/3.1.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/3.1.materials.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | struct Material { 5 | vec3 ambient; 6 | vec3 diffuse; 7 | vec3 specular; 8 | float shininess; 9 | }; 10 | 11 | struct Light { 12 | vec3 position; 13 | vec3 ambient; 14 | vec3 diffuse; 15 | vec3 specular; 16 | }; 17 | 18 | in vec3 FragPos; 19 | in vec3 Normal; 20 | 21 | uniform vec3 viewPos; 22 | uniform Material material; 23 | uniform Light light; 24 | 25 | void main() 26 | { 27 | // ambient 28 | vec3 ambient = light.ambient * material.ambient; 29 | 30 | // diffuse 31 | vec3 norm = normalize(Normal); 32 | vec3 lightDir = normalize(light.position - FragPos); 33 | float diff = max(dot(norm, lightDir), 0.0); 34 | vec3 diffuse = light.diffuse * (diff * material.diffuse); 35 | 36 | // specular 37 | vec3 viewDir = normalize(viewPos - FragPos); 38 | vec3 reflectDir = reflect(-lightDir, norm); 39 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 40 | vec3 specular = light.specular * (spec * material.specular); 41 | 42 | vec3 result = ambient + diffuse + specular; 43 | FragColor = vec4(result, 1.0); 44 | } 45 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/3.1.materials.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | 5 | out vec3 FragPos; 6 | out vec3 Normal; 7 | 8 | uniform mat4 model; 9 | uniform mat4 view; 10 | uniform mat4 projection; 11 | 12 | void main() 13 | { 14 | FragPos = vec3(model * vec4(aPos, 1.0)); 15 | Normal = mat3(transpose(inverse(model))) * aNormal; 16 | 17 | gl_Position = projection * view * vec4(FragPos, 1.0); 18 | } 19 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/4.1.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/4.1.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/4.1.lighting_maps.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | struct Material { 5 | sampler2D diffuse; 6 | vec3 specular; 7 | float shininess; 8 | }; 9 | 10 | struct Light { 11 | vec3 position; 12 | 13 | vec3 ambient; 14 | vec3 diffuse; 15 | vec3 specular; 16 | }; 17 | 18 | in vec3 FragPos; 19 | in vec3 Normal; 20 | in vec2 TexCoords; 21 | 22 | uniform vec3 viewPos; 23 | uniform Material material; 24 | uniform Light light; 25 | 26 | void main() 27 | { 28 | // ambient 29 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 30 | 31 | // diffuse 32 | vec3 norm = normalize(Normal); 33 | vec3 lightDir = normalize(light.position - FragPos); 34 | float diff = max(dot(norm, lightDir), 0.0); 35 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 36 | 37 | // specular 38 | vec3 viewDir = normalize(viewPos - FragPos); 39 | vec3 reflectDir = reflect(-lightDir, norm); 40 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 41 | vec3 specular = light.specular * (spec * material.specular); 42 | 43 | vec3 result = ambient + diffuse + specular; 44 | FragColor = vec4(result, 1.0); 45 | } 46 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/4.1.lighting_maps.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | layout (location = 2) in vec2 aTexCoords; 5 | 6 | out vec3 FragPos; 7 | out vec3 Normal; 8 | out vec2 TexCoords; 9 | 10 | uniform mat4 model; 11 | uniform mat4 view; 12 | uniform mat4 projection; 13 | 14 | void main() 15 | { 16 | FragPos = vec3(model * vec4(aPos, 1.0)); 17 | Normal = mat3(transpose(inverse(model))) * aNormal; 18 | TexCoords = aTexCoords; 19 | 20 | gl_Position = projection * view * vec4(FragPos, 1.0); 21 | } 22 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/4.2.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/4.2.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/4.2.lighting_maps.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | struct Material { 5 | sampler2D diffuse; 6 | sampler2D specular; 7 | float shininess; 8 | }; 9 | 10 | struct Light { 11 | vec3 position; 12 | 13 | vec3 ambient; 14 | vec3 diffuse; 15 | vec3 specular; 16 | }; 17 | 18 | in vec3 FragPos; 19 | in vec3 Normal; 20 | in vec2 TexCoords; 21 | 22 | uniform vec3 viewPos; 23 | uniform Material material; 24 | uniform Light light; 25 | 26 | void main() 27 | { 28 | // ambient 29 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 30 | 31 | // diffuse 32 | vec3 norm = normalize(Normal); 33 | vec3 lightDir = normalize(light.position - FragPos); 34 | float diff = max(dot(norm, lightDir), 0.0); 35 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 36 | 37 | // specular 38 | vec3 viewDir = normalize(viewPos - FragPos); 39 | vec3 reflectDir = reflect(-lightDir, norm); 40 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 41 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 42 | 43 | vec3 result = ambient + diffuse + specular; 44 | FragColor = vec4(result, 1.0); 45 | } 46 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/4.2.lighting_maps.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | layout (location = 2) in vec2 aTexCoords; 5 | 6 | out vec3 FragPos; 7 | out vec3 Normal; 8 | out vec2 TexCoords; 9 | 10 | uniform mat4 model; 11 | uniform mat4 view; 12 | uniform mat4 projection; 13 | 14 | void main() 15 | { 16 | FragPos = vec3(model * vec4(aPos, 1.0)); 17 | Normal = mat3(transpose(inverse(model))) * aNormal; 18 | TexCoords = aTexCoords; 19 | 20 | gl_Position = projection * view * vec4(FragPos, 1.0); 21 | } 22 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.1.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.1.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.1.light_casters.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | struct Material { 5 | sampler2D diffuse; 6 | sampler2D specular; 7 | float shininess; 8 | }; 9 | 10 | struct Light { 11 | //vec3 position; 12 | vec3 direction; 13 | 14 | vec3 ambient; 15 | vec3 diffuse; 16 | vec3 specular; 17 | }; 18 | 19 | in vec3 FragPos; 20 | in vec3 Normal; 21 | in vec2 TexCoords; 22 | 23 | uniform vec3 viewPos; 24 | uniform Material material; 25 | uniform Light light; 26 | 27 | void main() 28 | { 29 | // ambient 30 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 31 | 32 | // diffuse 33 | vec3 norm = normalize(Normal); 34 | // vec3 lightDir = normalize(light.position - FragPos); 35 | vec3 lightDir = normalize(-light.direction); 36 | float diff = max(dot(norm, lightDir), 0.0); 37 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 38 | 39 | // specular 40 | vec3 viewDir = normalize(viewPos - FragPos); 41 | vec3 reflectDir = reflect(-lightDir, norm); 42 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 43 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 44 | 45 | vec3 result = ambient + diffuse + specular; 46 | FragColor = vec4(result, 1.0); 47 | } 48 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.1.light_casters.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | layout (location = 2) in vec2 aTexCoords; 5 | 6 | out vec3 FragPos; 7 | out vec3 Normal; 8 | out vec2 TexCoords; 9 | 10 | uniform mat4 model; 11 | uniform mat4 view; 12 | uniform mat4 projection; 13 | 14 | void main() 15 | { 16 | FragPos = vec3(model * vec4(aPos, 1.0)); 17 | Normal = mat3(transpose(inverse(model))) * aNormal; 18 | TexCoords = aTexCoords; 19 | 20 | gl_Position = projection * view * vec4(FragPos, 1.0); 21 | } 22 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.2.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.2.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.2.light_casters.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | struct Material { 5 | sampler2D diffuse; 6 | sampler2D specular; 7 | float shininess; 8 | }; 9 | 10 | struct Light { 11 | vec3 position; 12 | 13 | vec3 ambient; 14 | vec3 diffuse; 15 | vec3 specular; 16 | 17 | float constant; 18 | float linear; 19 | float quadratic; 20 | }; 21 | 22 | in vec3 FragPos; 23 | in vec3 Normal; 24 | in vec2 TexCoords; 25 | 26 | uniform vec3 viewPos; 27 | uniform Material material; 28 | uniform Light light; 29 | 30 | void main() 31 | { 32 | // ambient 33 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 34 | 35 | // diffuse 36 | vec3 norm = normalize(Normal); 37 | vec3 lightDir = normalize(light.position - FragPos); 38 | float diff = max(dot(norm, lightDir), 0.0); 39 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 40 | 41 | // specular 42 | vec3 viewDir = normalize(viewPos - FragPos); 43 | vec3 reflectDir = reflect(-lightDir, norm); 44 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 45 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 46 | 47 | // attenuation 48 | float distance = length(light.position - FragPos); 49 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 50 | 51 | ambient *= attenuation; 52 | diffuse *= attenuation; 53 | specular *= attenuation; 54 | 55 | vec3 result = ambient + diffuse + specular; 56 | FragColor = vec4(result, 1.0); 57 | } 58 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.2.light_casters.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | layout (location = 2) in vec2 aTexCoords; 5 | 6 | out vec3 FragPos; 7 | out vec3 Normal; 8 | out vec2 TexCoords; 9 | 10 | uniform mat4 model; 11 | uniform mat4 view; 12 | uniform mat4 projection; 13 | 14 | void main() 15 | { 16 | FragPos = vec3(model * vec4(aPos, 1.0)); 17 | Normal = mat3(transpose(inverse(model))) * aNormal; 18 | TexCoords = aTexCoords; 19 | 20 | gl_Position = projection * view * vec4(FragPos, 1.0); 21 | } 22 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.3.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.3.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.3.light_casters.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | struct Material { 5 | sampler2D diffuse; 6 | sampler2D specular; 7 | float shininess; 8 | }; 9 | 10 | struct Light { 11 | vec3 position; 12 | vec3 direction; 13 | float cutOff; 14 | float outerCutOff; 15 | 16 | vec3 ambient; 17 | vec3 diffuse; 18 | vec3 specular; 19 | 20 | float constant; 21 | float linear; 22 | float quadratic; 23 | }; 24 | 25 | in vec3 FragPos; 26 | in vec3 Normal; 27 | in vec2 TexCoords; 28 | 29 | uniform vec3 viewPos; 30 | uniform Material material; 31 | uniform Light light; 32 | 33 | void main() 34 | { 35 | vec3 lightDir = normalize(light.position - FragPos); 36 | 37 | // check if lighting is inside the spotlight cone 38 | float theta = dot(lightDir, normalize(-light.direction)); 39 | 40 | if(theta > light.cutOff) // remember that we're working with angles as cosines instead of degrees so a '>' is used. 41 | { 42 | // ambient 43 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 44 | 45 | // diffuse 46 | vec3 norm = normalize(Normal); 47 | float diff = max(dot(norm, lightDir), 0.0); 48 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 49 | 50 | // specular 51 | vec3 viewDir = normalize(viewPos - FragPos); 52 | vec3 reflectDir = reflect(-lightDir, norm); 53 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 54 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 55 | 56 | // attenuation 57 | float distance = length(light.position - FragPos); 58 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 59 | 60 | // ambient *= attenuation; // remove attenuation from ambient, as otherwise at large distances the light would be darker inside than outside the spotlight due the ambient term in the else branche 61 | diffuse *= attenuation; 62 | specular *= attenuation; 63 | 64 | vec3 result = ambient + diffuse + specular; 65 | FragColor = vec4(result, 1.0); 66 | } 67 | else 68 | { 69 | // else, use ambient light so scene isn't completely dark outside the spotlight. 70 | FragColor = vec4(light.ambient * texture(material.diffuse, TexCoords).rgb, 1.0); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.3.light_casters.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | layout (location = 2) in vec2 aTexCoords; 5 | 6 | out vec3 FragPos; 7 | out vec3 Normal; 8 | out vec2 TexCoords; 9 | 10 | uniform mat4 model; 11 | uniform mat4 view; 12 | uniform mat4 projection; 13 | 14 | void main() 15 | { 16 | FragPos = vec3(model * vec4(aPos, 1.0)); 17 | Normal = mat3(transpose(inverse(model))) * aNormal; 18 | TexCoords = aTexCoords; 19 | 20 | gl_Position = projection * view * vec4(FragPos, 1.0); 21 | } 22 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.4.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.4.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.4.light_casters.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | struct Material { 5 | sampler2D diffuse; 6 | sampler2D specular; 7 | float shininess; 8 | }; 9 | 10 | struct Light { 11 | vec3 position; 12 | vec3 direction; 13 | float cutOff; 14 | float outerCutOff; 15 | 16 | vec3 ambient; 17 | vec3 diffuse; 18 | vec3 specular; 19 | 20 | float constant; 21 | float linear; 22 | float quadratic; 23 | }; 24 | 25 | in vec3 FragPos; 26 | in vec3 Normal; 27 | in vec2 TexCoords; 28 | 29 | uniform vec3 viewPos; 30 | uniform Material material; 31 | uniform Light light; 32 | 33 | void main() 34 | { 35 | // ambient 36 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 37 | 38 | // diffuse 39 | vec3 norm = normalize(Normal); 40 | vec3 lightDir = normalize(light.position - FragPos); 41 | float diff = max(dot(norm, lightDir), 0.0); 42 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 43 | 44 | // specular 45 | vec3 viewDir = normalize(viewPos - FragPos); 46 | vec3 reflectDir = reflect(-lightDir, norm); 47 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 48 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 49 | 50 | // spotlight (soft edges) 51 | float theta = dot(lightDir, normalize(-light.direction)); 52 | float epsilon = (light.cutOff - light.outerCutOff); 53 | float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); 54 | diffuse *= intensity; 55 | specular *= intensity; 56 | 57 | // attenuation 58 | float distance = length(light.position - FragPos); 59 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 60 | ambient *= attenuation; 61 | diffuse *= attenuation; 62 | specular *= attenuation; 63 | 64 | vec3 result = ambient + diffuse + specular; 65 | FragColor = vec4(result, 1.0); 66 | } 67 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/5.4.light_casters.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | layout (location = 2) in vec2 aTexCoords; 5 | 6 | out vec3 FragPos; 7 | out vec3 Normal; 8 | out vec2 TexCoords; 9 | 10 | uniform mat4 model; 11 | uniform mat4 view; 12 | uniform mat4 projection; 13 | 14 | void main() 15 | { 16 | FragPos = vec3(model * vec4(aPos, 1.0)); 17 | Normal = mat3(transpose(inverse(model))) * aNormal; 18 | TexCoords = aTexCoords; 19 | 20 | gl_Position = projection * view * vec4(FragPos, 1.0); 21 | } 22 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/6.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0); // set alle 4 vector values to 1.0 7 | } 8 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/6.lamp.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/6.multiple_lights.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | struct Material { 5 | sampler2D diffuse; 6 | sampler2D specular; 7 | float shininess; 8 | }; 9 | 10 | struct DirLight { 11 | vec3 direction; 12 | 13 | vec3 ambient; 14 | vec3 diffuse; 15 | vec3 specular; 16 | }; 17 | 18 | struct PointLight { 19 | vec3 position; 20 | 21 | float constant; 22 | float linear; 23 | float quadratic; 24 | 25 | vec3 ambient; 26 | vec3 diffuse; 27 | vec3 specular; 28 | }; 29 | 30 | struct SpotLight { 31 | vec3 position; 32 | vec3 direction; 33 | float cutOff; 34 | float outerCutOff; 35 | 36 | float constant; 37 | float linear; 38 | float quadratic; 39 | 40 | vec3 ambient; 41 | vec3 diffuse; 42 | vec3 specular; 43 | }; 44 | 45 | #define NR_POINT_LIGHTS 4 46 | 47 | in vec3 FragPos; 48 | in vec3 Normal; 49 | in vec2 TexCoords; 50 | 51 | uniform vec3 viewPos; 52 | uniform DirLight dirLight; 53 | uniform PointLight pointLights[NR_POINT_LIGHTS]; 54 | uniform SpotLight spotLight; 55 | uniform Material material; 56 | 57 | // function prototypes 58 | vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); 59 | vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); 60 | vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); 61 | 62 | void main() 63 | { 64 | // properties 65 | vec3 norm = normalize(Normal); 66 | vec3 viewDir = normalize(viewPos - FragPos); 67 | 68 | // == ===================================================== 69 | // Our lighting is set up in 3 phases: directional, point lights and an optional flashlight 70 | // For each phase, a calculate function is defined that calculates the corresponding color 71 | // per lamp. In the main() function we take all the calculated colors and sum them up for 72 | // this fragment's final color. 73 | // == ===================================================== 74 | // phase 1: directional lighting 75 | vec3 result = CalcDirLight(dirLight, norm, viewDir); 76 | // phase 2: point lights 77 | for(int i = 0; i < NR_POINT_LIGHTS; i++) 78 | result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); 79 | // phase 3: spot light 80 | result += CalcSpotLight(spotLight, norm, FragPos, viewDir); 81 | 82 | FragColor = vec4(result, 1.0); 83 | } 84 | 85 | // calculates the color when using a directional light. 86 | vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir) 87 | { 88 | vec3 lightDir = normalize(-light.direction); 89 | // diffuse shading 90 | float diff = max(dot(normal, lightDir), 0.0); 91 | // specular shading 92 | vec3 reflectDir = reflect(-lightDir, normal); 93 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 94 | // combine results 95 | vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); 96 | vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); 97 | vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); 98 | return (ambient + diffuse + specular); 99 | } 100 | 101 | // calculates the color when using a point light. 102 | vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) 103 | { 104 | vec3 lightDir = normalize(light.position - fragPos); 105 | // diffuse shading 106 | float diff = max(dot(normal, lightDir), 0.0); 107 | // specular shading 108 | vec3 reflectDir = reflect(-lightDir, normal); 109 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 110 | // attenuation 111 | float distance = length(light.position - fragPos); 112 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 113 | // combine results 114 | vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); 115 | vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); 116 | vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); 117 | ambient *= attenuation; 118 | diffuse *= attenuation; 119 | specular *= attenuation; 120 | return (ambient + diffuse + specular); 121 | } 122 | 123 | // calculates the color when using a spot light. 124 | vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) 125 | { 126 | vec3 lightDir = normalize(light.position - fragPos); 127 | // diffuse shading 128 | float diff = max(dot(normal, lightDir), 0.0); 129 | // specular shading 130 | vec3 reflectDir = reflect(-lightDir, normal); 131 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 132 | // attenuation 133 | float distance = length(light.position - fragPos); 134 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 135 | // spotlight intensity 136 | float theta = dot(lightDir, normalize(-light.direction)); 137 | float epsilon = light.cutOff - light.outerCutOff; 138 | float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); 139 | // combine results 140 | vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); 141 | vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); 142 | vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); 143 | ambient *= attenuation * intensity; 144 | diffuse *= attenuation * intensity; 145 | specular *= attenuation * intensity; 146 | return (ambient + diffuse + specular); 147 | } 148 | -------------------------------------------------------------------------------- /src/_2_lighting/shaders/6.multiple_lights.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | layout (location = 2) in vec2 aTexCoords; 5 | 6 | out vec3 FragPos; 7 | out vec3 Normal; 8 | out vec2 TexCoords; 9 | 10 | uniform mat4 model; 11 | uniform mat4 view; 12 | uniform mat4 projection; 13 | 14 | void main() 15 | { 16 | FragPos = vec3(model * vec4(aPos, 1.0)); 17 | Normal = mat3(transpose(inverse(model))) * aNormal; 18 | TexCoords = aTexCoords; 19 | 20 | gl_Position = projection * view * vec4(FragPos, 1.0); 21 | } 22 | -------------------------------------------------------------------------------- /src/_3_model_loading/README.md: -------------------------------------------------------------------------------- 1 | ### Tutorials 2 | [Assimp](https://learnopengl.com/#!Model-Loading/Assimp)
3 | [Mesh](https://learnopengl.com/#!Model-Loading/Mesh)
4 | * see also [`../mesh.rs`](../mesh.rs) 5 | 6 | [Model](https://learnopengl.com/#!Model-Loading/Model)
7 | * see also [`../model.rs`](../model.rs) 8 | -------------------------------------------------------------------------------- /src/_3_model_loading/_1_model_loading.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use glutin::event::{Event, VirtualKeyCode, WindowEvent, ElementState, MouseButton}; 3 | use glutin::event_loop::ControlFlow; 4 | use std::rc::Rc; 5 | use crate::{model::Model, camera::{Camera, Directions}, shader::Shader}; 6 | extern crate nalgebra_glm as glm; 7 | 8 | const SCR_WIDTH: u32 = 800; 9 | const SCR_HEIGHT: u32 = 600; 10 | 11 | 12 | pub fn main_3_1() { 13 | unsafe 14 | { 15 | let event_loop = glutin::event_loop::EventLoop::new(); 16 | let window_builder = glutin::window::WindowBuilder::new() 17 | .with_title("learn-opengl-glow => _1_model_loading") 18 | .with_inner_size(glutin::dpi::LogicalSize::new(SCR_WIDTH, SCR_HEIGHT)); 19 | let window = glutin::ContextBuilder::new() 20 | .with_vsync(true) 21 | .build_windowed(window_builder, &event_loop) 22 | .unwrap() 23 | .make_current() 24 | .unwrap(); 25 | let gl=Rc::new( glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _)); 26 | 27 | //let our_model = Model::new(gl.clone(), "resources/objects/backpack/backpack.obj"); 28 | //let our_model = Model::new(gl.clone(), "resources/objects/nanosuit/nanosuit.obj"); 29 | let our_model = Model::new(gl.clone(), "resources/objects/cyborg/cyborg.obj"); 30 | //let our_model = Model::new(gl.clone(), "resources/objects/rock/rock.obj"); 31 | //let our_model = Model::new(gl.clone(), "resources/objects/cube/cube.obj"); 32 | 33 | let shader = Shader::new_from_files( 34 | gl.clone(), 35 | "src/_3_model_loading/shaders/1.model_loading.vs", 36 | "src/_3_model_loading/shaders/1.model_loading.fs" 37 | ); 38 | 39 | let mut camera = Camera::new(glm::vec3( 2.0, 2.0, 10.0)); 40 | 41 | let mut is_dragging = false; 42 | let mut last_x = SCR_WIDTH as f32 / 2.0; 43 | let mut last_y = SCR_HEIGHT as f32 / 2.0; 44 | 45 | const DESIRED_FRAME_TIME :f32 = 0.02; 46 | let mut last_draw_time = std::time::Instant::now(); 47 | let mut _frame_time= 0.0f32; 48 | 49 | event_loop.run(move |event, _, control_flow| { 50 | 51 | let now = std::time::Instant::now(); 52 | let elapsed_time = now.duration_since(last_draw_time).as_secs_f32(); 53 | 54 | if elapsed_time > DESIRED_FRAME_TIME { 55 | _frame_time += elapsed_time; 56 | window.window().request_redraw(); 57 | last_draw_time = now; 58 | } 59 | 60 | // wireframe 61 | //gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); 62 | 63 | match event { 64 | Event::RedrawRequested(_) => { 65 | // DRAW HERE 66 | gl.clear_color(0.2, 0.3, 0.3, 1.0); 67 | gl.enable(glow::DEPTH_TEST); 68 | gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT); 69 | 70 | let aspect = SCR_WIDTH as f32/ SCR_HEIGHT as f32; 71 | let projection = glm::perspective(aspect, camera.get_zoom().to_radians(), 0.1f32, 100.0f32); 72 | let model = glm::translate(&glm::Mat4::identity(), &glm::vec3(0.0, -1.75, 0.0)); 73 | 74 | shader.use_program(); 75 | shader.set_uniform_mat4("view", &camera.get_view_matrix()); 76 | shader.set_uniform_mat4("projection", &projection); 77 | shader.set_uniform_mat4("model", &model); 78 | 79 | our_model.draw(&shader); 80 | window.swap_buffers().unwrap(); 81 | }, 82 | 83 | Event::WindowEvent { ref event, .. } => match event { 84 | WindowEvent::Resized(physical_size) => window.resize(*physical_size), 85 | WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, 86 | WindowEvent::KeyboardInput { device_id:_, input, is_synthetic:_ } => { 87 | match input.virtual_keycode { 88 | Some(key) => { 89 | match key { 90 | VirtualKeyCode::Escape => *control_flow = glutin::event_loop::ControlFlow::Exit, 91 | VirtualKeyCode::W => camera.key_interact(Directions::Forward), 92 | VirtualKeyCode::A => camera.key_interact(Directions::Left), 93 | VirtualKeyCode::S => camera.key_interact(Directions::Backward), 94 | VirtualKeyCode::D => camera.key_interact(Directions::Right), 95 | VirtualKeyCode::Up => camera.key_interact(Directions::Up), 96 | VirtualKeyCode::Down => camera.key_interact(Directions::Down), 97 | VirtualKeyCode::Left => camera.key_interact(Directions::Left), 98 | VirtualKeyCode::Right=> camera.key_interact(Directions::Right), 99 | _ => (), 100 | } 101 | }, 102 | _ => (), 103 | } 104 | }, 105 | WindowEvent::CursorMoved { device_id:_, position, .. } => { 106 | //println!("Move to {:?}", position); 107 | let new_x = position.x as f32; 108 | let new_y = position.y as f32; 109 | 110 | if is_dragging { 111 | camera.mouse_interact(new_x - last_x, new_y - last_y); 112 | } 113 | last_x = new_x; 114 | last_y = new_y; 115 | }, 116 | 117 | WindowEvent::MouseInput { device_id:_, state, button, .. } => { 118 | if state == &ElementState::Pressed && button == &MouseButton::Left { 119 | is_dragging = true; 120 | } else { 121 | is_dragging = false; 122 | } 123 | }, 124 | 125 | WindowEvent::MouseWheel { device_id:_, delta, phase :_, .. } => { 126 | match delta { 127 | glutin::event::MouseScrollDelta::LineDelta(_x,y) => { 128 | camera.scroll_wheel_interact(*y); 129 | }, 130 | _ => (), 131 | } 132 | }, 133 | _=> {} 134 | }, 135 | 136 | Event::LoopDestroyed => { 137 | // CLEANUP 138 | }, 139 | _ => {} 140 | } 141 | } ); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/_3_model_loading/mod.rs: -------------------------------------------------------------------------------- 1 | mod _1_model_loading; 2 | pub use self::_1_model_loading::*; 3 | 4 | // mod mesh_tester; 5 | // pub use self::mesh_tester::*; 6 | 7 | -------------------------------------------------------------------------------- /src/_3_model_loading/shaders/1.model_loading.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture1, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_3_model_loading/shaders/1.model_loading.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | layout (location = 2) in vec2 aTexCoords; 5 | 6 | out vec2 TexCoords; 7 | 8 | uniform mat4 model; 9 | uniform mat4 view; 10 | uniform mat4 projection; 11 | 12 | void main() 13 | { 14 | TexCoords = aTexCoords; 15 | gl_Position = projection * view * model * vec4(aPos, 1.0); 16 | } 17 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/README.md: -------------------------------------------------------------------------------- 1 | ### Tutorials 2 | [Depth-testing](https://learnopengl.com/#!Advanced-OpenGL/Depth-testing)
3 | [Stencil-testing](https://learnopengl.com/#!Advanced-OpenGL/Stencil-testing)
4 | [Blending](https://learnopengl.com/#!Advanced-OpenGL/Blending)
5 | [Face-culling](https://learnopengl.com/#!Advanced-OpenGL/Face-culling)
6 | [Framebuffers](https://learnopengl.com/#!Advanced-OpenGL/Framebuffers)
7 | [Cubemaps](https://learnopengl.com/#!Advanced-OpenGL/Cubemaps)
8 | [Advanced-Data](https://learnopengl.com/#!Advanced-OpenGL/Advanced-Data)
9 | [Advanced-GLSL](https://learnopengl.com/#!Advanced-OpenGL/Advanced-GLSL)
10 | [Geometry-Shader](https://learnopengl.com/#!Advanced-OpenGL/Geometry-Shader)
11 | [Instancing](https://learnopengl.com/#!Advanced-OpenGL/Instancing)
12 | [Anti-Aliasing](https://learnopengl.com/#!Advanced-OpenGL/Anti-Aliasing)
13 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/mod.rs: -------------------------------------------------------------------------------- 1 | mod _1_1_depth_testing; 2 | pub use self::_1_1_depth_testing::*; 3 | mod _1_2_depth_testing_view; 4 | pub use self::_1_2_depth_testing_view::*; 5 | mod _2_stencil_testing; 6 | pub use self::_2_stencil_testing::*; 7 | mod _3_1_blending_discard; 8 | pub use self::_3_1_blending_discard::*; 9 | mod _3_2_blending_sorted; 10 | pub use self::_3_2_blending_sorted::*; 11 | mod _5_1_framebuffers; 12 | pub use self::_5_1_framebuffers::*; 13 | // mod _6_1_cubemaps_skybox; 14 | // pub use self::_6_1_cubemaps_skybox::*; 15 | // mod _6_2_cubemaps_environment_mapping; 16 | // pub use self::_6_2_cubemaps_environment_mapping::*; 17 | // mod _8_advanced_glsl_ubo; 18 | // pub use self::_8_advanced_glsl_ubo::*; 19 | // mod _9_1_geometry_shader_houses; 20 | // pub use self::_9_1_geometry_shader_houses::*; 21 | // mod _9_2_geometry_shader_exploding; 22 | // pub use self::_9_2_geometry_shader_exploding::*; 23 | // mod _9_3_normal_visualization; 24 | // pub use self::_9_3_normal_visualization::*; 25 | // mod _10_1_instancing_quads; 26 | // pub use self::_10_1_instancing_quads::*; 27 | // mod _10_2_asteroids; 28 | // pub use self::_10_2_asteroids::*; 29 | // mod _10_3_asteroids_instanced; 30 | // pub use self::_10_3_asteroids_instanced::*; 31 | // mod _11_anti_aliasing_offscreen; 32 | // pub use self::_11_anti_aliasing_offscreen::*; 33 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/1.1.depth_testing.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture1, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/1.1.depth_testing.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/1.2.depth_testing.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | float near = 0.1; 5 | float far = 100.0; 6 | float LinearizeDepth(float depth) 7 | { 8 | float z = depth * 2.0 - 1.0; // back to NDC 9 | return (2.0 * near * far) / (far + near - z * (far - near)); 10 | } 11 | 12 | void main() 13 | { 14 | float depth = LinearizeDepth(gl_FragCoord.z) / far; // divide by far to get depth in range [0,1] for visualization purposes 15 | FragColor = vec4(vec3(depth), 1.0); 16 | } 17 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/1.2.depth_testing.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/10.1.instancing.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 fColor; 5 | 6 | void main() 7 | { 8 | FragColor = vec4(fColor, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/10.1.instancing.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec2 aPos; 3 | layout (location = 1) in vec3 aColor; 4 | layout (location = 2) in vec2 aOffset; 5 | 6 | out vec3 fColor; 7 | 8 | void main() 9 | { 10 | fColor = aColor; 11 | gl_Position = vec4(aPos + aOffset, 0.0, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/10.2.instancing.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture_diffuse1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture_diffuse1, TexCoords); 11 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/10.2.instancing.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 2) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 projection; 8 | uniform mat4 view; 9 | uniform mat4 model; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 15 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/10.3.asteroids.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture_diffuse1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture_diffuse1, TexCoords); 11 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/10.3.asteroids.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 2) in vec2 aTexCoords; 4 | layout (location = 3) in mat4 aInstanceMatrix; 5 | 6 | out vec2 TexCoords; 7 | 8 | uniform mat4 projection; 9 | uniform mat4 view; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * aInstanceMatrix * vec4(aPos, 1.0f); 15 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/10.3.planet.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture_diffuse1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture_diffuse1, TexCoords); 11 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/10.3.planet.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 2) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 projection; 8 | uniform mat4 view; 9 | uniform mat4 model; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 15 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/11.aa_post.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D screenTexture; 7 | 8 | void main() 9 | { 10 | vec3 col = texture(screenTexture, TexCoords).rgb; 11 | float grayscale = 0.2126 * col.r + 0.7152 * col.g + 0.0722 * col.b; 12 | FragColor = vec4(vec3(grayscale), 1.0); 13 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/11.aa_post.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec2 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | void main() 8 | { 9 | TexCoords = aTexCoords; 10 | gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); 11 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/11.anti_aliasing.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(0.0, 1.0, 0.0, 1.0); 7 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/11.anti_aliasing.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | uniform mat4 model; 5 | uniform mat4 view; 6 | uniform mat4 projection; 7 | 8 | void main() 9 | { 10 | gl_Position = projection * view * model * vec4(aPos, 1.0); 11 | } -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/2.stencil_single_color.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(0.04, 0.28, 0.26, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/2.stencil_testing.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture1, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/2.stencil_testing.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0f); 15 | } 16 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/3.1.blending.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture1; 7 | 8 | void main() 9 | { 10 | vec4 texColor = texture(texture1, TexCoords); 11 | if(texColor.a < 0.1) 12 | discard; 13 | FragColor = texColor; 14 | } 15 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/3.1.blending.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/3.2.blending.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture1, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/3.2.blending.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/5.1.framebuffers.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture1, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/5.1.framebuffers.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/5.1.framebuffers_screen.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D screenTexture; 7 | 8 | void main() 9 | { 10 | vec3 col = texture(screenTexture, TexCoords).rgb; 11 | FragColor = vec4(col, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/5.1.framebuffers_screen.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec2 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | void main() 8 | { 9 | TexCoords = aTexCoords; 10 | gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/6.1.cubemaps.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture1, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/6.1.cubemaps.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 model; 8 | uniform mat4 view; 9 | uniform mat4 projection; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/6.1.skybox.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 TexCoords; 5 | 6 | uniform samplerCube skybox; 7 | 8 | void main() 9 | { 10 | FragColor = texture(skybox, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/6.1.skybox.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | out vec3 TexCoords; 5 | 6 | uniform mat4 projection; 7 | uniform mat4 view; 8 | 9 | void main() 10 | { 11 | TexCoords = aPos; 12 | vec4 pos = projection * view * vec4(aPos, 1.0); 13 | gl_Position = pos.xyww; 14 | } 15 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/6.2.cubemaps.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 Normal; 5 | in vec3 Position; 6 | 7 | uniform vec3 cameraPos; 8 | uniform samplerCube skybox; 9 | 10 | void main() 11 | { 12 | vec3 I = normalize(Position - cameraPos); 13 | vec3 R = reflect(I, normalize(Normal)); 14 | FragColor = vec4(texture(skybox, R).rgb, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/6.2.cubemaps.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | 5 | out vec3 Normal; 6 | out vec3 Position; 7 | 8 | uniform mat4 model; 9 | uniform mat4 view; 10 | uniform mat4 projection; 11 | 12 | void main() 13 | { 14 | Normal = mat3(transpose(inverse(model))) * aNormal; 15 | Position = vec3(model * vec4(aPos, 1.0)); 16 | gl_Position = projection * view * model * vec4(aPos, 1.0); 17 | } 18 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/6.2.skybox.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 TexCoords; 5 | 6 | uniform samplerCube skybox; 7 | 8 | void main() 9 | { 10 | FragColor = texture(skybox, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/6.2.skybox.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | out vec3 TexCoords; 5 | 6 | uniform mat4 projection; 7 | uniform mat4 view; 8 | 9 | void main() 10 | { 11 | TexCoords = aPos; 12 | vec4 pos = projection * view * vec4(aPos, 1.0); 13 | gl_Position = pos.xyww; 14 | } 15 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/8.advanced_glsl.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | 4 | layout (std140) uniform Matrices 5 | { 6 | mat4 projection; 7 | mat4 view; 8 | }; 9 | uniform mat4 model; 10 | 11 | void main() 12 | { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/8.blue.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(0.0, 0.0, 1.0, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/8.green.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(0.0, 1.0, 0.0, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/8.red.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0, 0.0, 0.0, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/8.yellow.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0, 1.0, 0.0, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.1.geometry_shader.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec3 fColor; 5 | 6 | void main() 7 | { 8 | FragColor = vec4(fColor, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.1.geometry_shader.gs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (points) in; 3 | layout (triangle_strip, max_vertices = 5) out; 4 | 5 | in VS_OUT { 6 | vec3 color; 7 | } gs_in[]; 8 | 9 | out vec3 fColor; 10 | 11 | void build_house(vec4 position) 12 | { 13 | fColor = gs_in[0].color; // gs_in[0] since there's only one input vertex 14 | gl_Position = position + vec4(-0.2, -0.2, 0.0, 0.0); // 1:bottom-left 15 | EmitVertex(); 16 | gl_Position = position + vec4( 0.2, -0.2, 0.0, 0.0); // 2:bottom-right 17 | EmitVertex(); 18 | gl_Position = position + vec4(-0.2, 0.2, 0.0, 0.0); // 3:top-left 19 | EmitVertex(); 20 | gl_Position = position + vec4( 0.2, 0.2, 0.0, 0.0); // 4:top-right 21 | EmitVertex(); 22 | gl_Position = position + vec4( 0.0, 0.4, 0.0, 0.0); // 5:top 23 | fColor = vec3(1.0, 1.0, 1.0); 24 | EmitVertex(); 25 | EndPrimitive(); 26 | } 27 | 28 | void main() { 29 | build_house(gl_in[0].gl_Position); 30 | } 31 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.1.geometry_shader.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec2 aPos; 3 | layout (location = 1) in vec3 aColor; 4 | 5 | out VS_OUT { 6 | vec3 color; 7 | } vs_out; 8 | 9 | void main() 10 | { 11 | vs_out.color = aColor; 12 | gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); 13 | } 14 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.2.geometry_shader.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture_diffuse1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture_diffuse1, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.2.geometry_shader.gs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (triangles) in; 3 | layout (triangle_strip, max_vertices = 3) out; 4 | 5 | in VS_OUT { 6 | vec2 texCoords; 7 | } gs_in[]; 8 | 9 | out vec2 TexCoords; 10 | 11 | uniform float time; 12 | 13 | vec4 explode(vec4 position, vec3 normal) 14 | { 15 | float magnitude = 2.0; 16 | vec3 direction = normal * ((sin(time) + 1.0) / 2.0) * magnitude; 17 | return position + vec4(direction, 0.0); 18 | } 19 | 20 | vec3 GetNormal() 21 | { 22 | vec3 a = vec3(gl_in[0].gl_Position) - vec3(gl_in[1].gl_Position); 23 | vec3 b = vec3(gl_in[2].gl_Position) - vec3(gl_in[1].gl_Position); 24 | return normalize(cross(a, b)); 25 | } 26 | 27 | void main() { 28 | vec3 normal = GetNormal(); 29 | 30 | gl_Position = explode(gl_in[0].gl_Position, normal); 31 | TexCoords = gs_in[0].texCoords; 32 | EmitVertex(); 33 | gl_Position = explode(gl_in[1].gl_Position, normal); 34 | TexCoords = gs_in[1].texCoords; 35 | EmitVertex(); 36 | gl_Position = explode(gl_in[2].gl_Position, normal); 37 | TexCoords = gs_in[2].texCoords; 38 | EmitVertex(); 39 | EndPrimitive(); 40 | } 41 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.2.geometry_shader.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 2) in vec2 aTexCoords; 4 | 5 | out VS_OUT { 6 | vec2 texCoords; 7 | } vs_out; 8 | 9 | uniform mat4 projection; 10 | uniform mat4 view; 11 | uniform mat4 model; 12 | 13 | void main() 14 | { 15 | vs_out.texCoords = aTexCoords; 16 | gl_Position = projection * view * model * vec4(aPos, 1.0); 17 | } 18 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.3.default.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | in vec2 TexCoords; 5 | 6 | uniform sampler2D texture_diffuse1; 7 | 8 | void main() 9 | { 10 | FragColor = texture(texture_diffuse1, TexCoords); 11 | } 12 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.3.default.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 2) in vec2 aTexCoords; 4 | 5 | out vec2 TexCoords; 6 | 7 | uniform mat4 projection; 8 | uniform mat4 view; 9 | uniform mat4 model; 10 | 11 | void main() 12 | { 13 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.3.normal_visualization.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() 5 | { 6 | FragColor = vec4(1.0, 1.0, 0.0, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.3.normal_visualization.gs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (triangles) in; 3 | layout (line_strip, max_vertices = 6) out; 4 | 5 | in VS_OUT { 6 | vec3 normal; 7 | } gs_in[]; 8 | 9 | const float MAGNITUDE = 0.006; 10 | 11 | void GenerateLine(int index) 12 | { 13 | gl_Position = gl_in[index].gl_Position; 14 | EmitVertex(); 15 | gl_Position = gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE; 16 | EmitVertex(); 17 | EndPrimitive(); 18 | } 19 | 20 | void main() 21 | { 22 | GenerateLine(0); // first vertex normal 23 | GenerateLine(1); // second vertex normal 24 | GenerateLine(2); // third vertex normal 25 | } 26 | -------------------------------------------------------------------------------- /src/_4_advanced_opengl/shaders/9.3.normal_visualization.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 aPos; 3 | layout (location = 1) in vec3 aNormal; 4 | 5 | out VS_OUT { 6 | vec3 normal; 7 | } vs_out; 8 | 9 | uniform mat4 projection; 10 | uniform mat4 view; 11 | uniform mat4 model; 12 | 13 | void main() 14 | { 15 | mat3 normalMatrix = mat3(transpose(inverse(view * model))); 16 | vs_out.normal = vec3(projection * vec4(normalMatrix * aNormal, 1.0)); 17 | gl_Position = projection * view * model * vec4(aPos, 1.0); 18 | } 19 | -------------------------------------------------------------------------------- /src/_7_in_practice/README.md: -------------------------------------------------------------------------------- 1 | ### Tutorials 2 | [Debugging](https://learnopengl.com/#!In-Practice/Debugging) 3 | -------------------------------------------------------------------------------- /src/_7_in_practice/mod.rs: -------------------------------------------------------------------------------- 1 | mod _1_debugging; 2 | pub use self::_1_debugging::*; 3 | 4 | mod _2_text_rendering; 5 | pub use self::_2_text_rendering::*; 6 | -------------------------------------------------------------------------------- /src/_7_in_practice/shaders/debugging.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | in vec2 TexCoords; 4 | 5 | uniform sampler2D tex; 6 | 7 | void main() 8 | { 9 | FragColor = texture(tex, TexCoords); 10 | } 11 | -------------------------------------------------------------------------------- /src/_7_in_practice/shaders/debugging.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec3 position; 3 | layout (location = 1) in vec2 texCoords; 4 | 5 | uniform mat4 projection; 6 | uniform mat4 model; 7 | 8 | out vec2 TexCoords; 9 | 10 | void main() 11 | { 12 | gl_Position = projection * model * vec4(position, 1.0f); 13 | TexCoords = texCoords; 14 | } 15 | -------------------------------------------------------------------------------- /src/_7_in_practice/shaders/text.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | in vec2 TexCoords; 3 | out vec4 color; 4 | 5 | uniform sampler2D text; 6 | uniform vec3 textColor; 7 | 8 | void main() 9 | { 10 | vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r); 11 | color = vec4(textColor, 1.0) * sampled; 12 | // color = vec4(1.0,0.7,0.9,1.0); 13 | } -------------------------------------------------------------------------------- /src/_7_in_practice/shaders/text.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | layout (location = 0) in vec4 vertex; // 3 | out vec2 TexCoords; 4 | 5 | uniform mat4 projection; 6 | 7 | void main() 8 | { 9 | gl_Position = projection * vec4(vertex.xy, 0.0, 1.0); 10 | TexCoords = vertex.zw; 11 | } -------------------------------------------------------------------------------- /src/camera.rs: -------------------------------------------------------------------------------- 1 | extern crate nalgebra_glm as glm; 2 | 3 | pub enum Directions { 4 | Left, 5 | Right, 6 | Up, 7 | Down, 8 | Forward, 9 | Backward, 10 | } 11 | 12 | #[derive(Debug, Copy, Clone, PartialEq)] 13 | pub struct Camera { 14 | position : glm::Vec3, 15 | front : glm::Vec3, 16 | up : glm::Vec3, 17 | right : glm::Vec3, 18 | world_up : glm::Vec3, 19 | 20 | yaw : f32, 21 | pitch : f32, 22 | speed : f32, 23 | sensitivity : f32, 24 | zoom : f32, 25 | } 26 | 27 | impl Camera { 28 | pub fn new( position: glm::Vec3 ) -> Self { 29 | 30 | let yaw = -90.0f32; 31 | let pitch = 0.0f32; 32 | let world_up = glm::vec3(0.0,1.0,0.0 ); 33 | let front = Camera::calc_front(yaw, pitch); 34 | let right = Camera::calc_right(&front, &world_up); 35 | let up = Camera::calc_up(&right, &front); 36 | 37 | Self { 38 | position, 39 | front, 40 | up, 41 | right, 42 | world_up , 43 | yaw, 44 | pitch, 45 | speed : 2.5f32, 46 | sensitivity : 0.1f32, 47 | zoom : 45.0f32, 48 | } 49 | } 50 | 51 | 52 | pub fn get_zoom(&self) -> f32 {self.zoom} 53 | pub fn get_position(&self) -> &glm::Vec3 {&self.position} 54 | pub fn get_front(&self) -> &glm::Vec3 {&self.front} 55 | 56 | pub fn get_view_matrix(&self) -> glm::Mat4 57 | { 58 | glm::look_at(&self.position, &(self.position + self.front), &self.up) 59 | } 60 | 61 | 62 | pub fn key_interact(&mut self, direction: Directions ) { 63 | 64 | let velocity = self.speed * 0.16f32; 65 | 66 | match direction { 67 | Directions::Forward => { 68 | self.position += self.front * velocity; 69 | } 70 | Directions::Left => { 71 | self.position -= self.right * velocity; 72 | } 73 | Directions::Right => { 74 | self.position += self.right * velocity; 75 | } 76 | Directions::Up => { 77 | self.position += self.up * velocity; 78 | } 79 | Directions::Down => { 80 | self.position -= self.up * velocity; 81 | } 82 | Directions::Backward => { 83 | self.position -= self.front * velocity; 84 | } 85 | } 86 | } 87 | 88 | pub fn mouse_interact(&mut self, dx: f32, dy : f32 ) { 89 | 90 | self.yaw = self.yaw + dx * self.sensitivity; 91 | self.pitch = (self.pitch - dy * self.sensitivity).max(-89.0).min(89.0); 92 | 93 | self.front = Camera::calc_front(self.yaw, self.pitch); 94 | self.right = Camera::calc_right(&self.front, &self.world_up); 95 | self.up = Camera::calc_up(&self.right, &self.front); 96 | } 97 | 98 | pub fn scroll_wheel_interact(&mut self, delta: f32 ) { 99 | let new_zoom = (self.zoom + delta).max(1.0).min(55.0); 100 | //println!("Scroll {} + delta {} => {}", self.zoom, delta, new_zoom ); 101 | self.zoom = new_zoom; 102 | } 103 | 104 | fn calc_front(yaw:f32, pitch: f32) -> glm::Vec3 { 105 | let ya = yaw.to_radians(); 106 | let pa = pitch.to_radians(); 107 | 108 | glm::vec3( 109 | ya.cos() * pa.cos(), 110 | pa.sin(), 111 | ya.sin() * pa.cos() ) 112 | .normalize() 113 | } 114 | 115 | fn calc_right(front :&glm::Vec3, world_up: &glm::Vec3) -> glm::Vec3 { 116 | glm::cross(front, world_up).normalize() 117 | } 118 | 119 | fn calc_up(right :&glm::Vec3, front: &glm::Vec3) -> glm::Vec3 { 120 | glm::cross(right, front).normalize() 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | //mod common; 2 | pub mod shader; 3 | //mod macros; 4 | pub mod camera; 5 | pub mod texture; 6 | pub mod mesh; 7 | pub mod mesh_cube; 8 | pub mod model; 9 | //mod utils; 10 | 11 | #[cfg(feature = "chapter-1")] 12 | mod _1_getting_started; 13 | #[cfg(feature = "chapter-1")] 14 | use _1_getting_started::*; 15 | 16 | #[cfg(feature = "chapter-2")] 17 | mod _2_lighting; 18 | #[cfg(feature = "chapter-2")] 19 | use _2_lighting::*; 20 | 21 | #[cfg(feature = "chapter-3")] 22 | mod _3_model_loading; 23 | #[cfg(feature = "chapter-3")] 24 | use _3_model_loading::*; 25 | 26 | #[cfg(feature = "chapter-4")] 27 | mod _4_advanced_opengl; 28 | #[cfg(feature = "chapter-4")] 29 | use _4_advanced_opengl::*; 30 | 31 | // #[cfg(feature = "chapter-5")] 32 | // mod _5_advanced_lighting; 33 | // #[cfg(feature = "chapter-5")] 34 | // use _5_advanced_lighting::*; 35 | 36 | // #[cfg(feature = "chapter-6")] 37 | // mod _6_pbr; 38 | // #[cfg(feature = "chapter-6")] 39 | // use _6_pbr::*; 40 | 41 | #[cfg(feature = "chapter-7")] 42 | mod _7_in_practice; 43 | #[cfg(feature = "chapter-7")] 44 | use _7_in_practice::*; 45 | 46 | 47 | 48 | fn main() { 49 | let args: Vec = std::env::args().collect(); 50 | if args.len() != 2 { 51 | println!("Call with the number of the tutorial, e.g. `1_1_2` for _1_2_hello_window_clear.rs"); 52 | std::process::exit(1); 53 | } 54 | let tutorial_id = &args[1]; 55 | 56 | match tutorial_id.as_str() { 57 | #[cfg(feature = "chapter-1")] "1_1_1" => main_1_1_1(), 58 | #[cfg(feature = "chapter-1")] "1_1_2" => main_1_1_2(), 59 | #[cfg(feature = "chapter-1")] "1_2_1" => main_1_2_1(), 60 | #[cfg(feature = "chapter-1")] "1_2_2" => main_1_2_2(), 61 | #[cfg(feature = "chapter-1")] "1_2_3" => main_1_2_3(), 62 | #[cfg(feature = "chapter-1")] "1_2_4" => main_1_2_4(), 63 | #[cfg(feature = "chapter-1")] "1_2_5" => main_1_2_5(), 64 | #[cfg(feature = "chapter-1")] "1_3_1" => main_1_3_1(), 65 | #[cfg(feature = "chapter-1")] "1_3_2" => main_1_3_2(), 66 | #[cfg(feature = "chapter-1")] "1_3_3" => main_1_3_3(), 67 | #[cfg(feature = "chapter-1")] "1_4_1" => main_1_4_1(), 68 | #[cfg(feature = "chapter-1")] "1_4_2" => main_1_4_2(), 69 | #[cfg(feature = "chapter-1")] "1_5_1" => main_1_5_1(), 70 | #[cfg(feature = "chapter-1")] "1_6_1" => main_1_6_1(), 71 | #[cfg(feature = "chapter-1")] "1_6_2" => main_1_6_2(), 72 | #[cfg(feature = "chapter-1")] "1_6_3" => main_1_6_3(), 73 | #[cfg(feature = "chapter-1")] "1_7_1" => main_1_7_1(), 74 | #[cfg(feature = "chapter-1")] "1_7_2" => main_1_7_2(), 75 | #[cfg(feature = "chapter-1")] "1_7_3" => main_1_7_3(), 76 | #[cfg(feature = "chapter-1")] "1_7_4" => main_1_7_4(), 77 | 78 | #[cfg(feature = "chapter-2")] "2_1" => main_2_1(), 79 | #[cfg(feature = "chapter-2")] "2_2_1" => main_2_2_1(), 80 | #[cfg(feature = "chapter-2")] "2_2_2" => main_2_2_2(), 81 | #[cfg(feature = "chapter-2")] "2_3_1" => main_2_3_1(), 82 | #[cfg(feature = "chapter-2")] "2_4_1" => main_2_4_1(), 83 | #[cfg(feature = "chapter-2")] "2_4_2" => main_2_4_2(), 84 | #[cfg(feature = "chapter-2")] "2_5_1" => main_2_5_1(), 85 | #[cfg(feature = "chapter-2")] "2_5_2" => main_2_5_2(), 86 | #[cfg(feature = "chapter-2")] "2_5_3" => main_2_5_3(), 87 | #[cfg(feature = "chapter-2")] "2_5_4" => main_2_5_4(), 88 | // #[cfg(feature = "chapter-2")] "2_6" | "latest" => main_2_6(), 89 | 90 | #[cfg(feature = "chapter-3")] "3_1" => main_3_1(), 91 | 92 | #[cfg(feature = "chapter-4")] "4_1_1" => main_4_1_1(), 93 | #[cfg(feature = "chapter-4")] "4_1_2" => main_4_1_2(), 94 | #[cfg(feature = "chapter-4")] "4_2" => main_4_2(), 95 | #[cfg(feature = "chapter-4")] "4_3_1" => main_4_3_1(), 96 | #[cfg(feature = "chapter-4")] "4_3_2" => main_4_3_2(), 97 | #[cfg(feature = "chapter-4")] "4_5_1" | "latest"=> main_4_5_1(), 98 | // #[cfg(feature = "chapter-4")] "4_6_1" | "latest"=> main_4_6_1(), 99 | // #[cfg(feature = "chapter-4")] "4_6_2" | "latest"=> main_4_6_2(), 100 | // #[cfg(feature = "chapter-4")] "4_8" | "latest"=> main_4_8(), 101 | // #[cfg(feature = "chapter-4")] "4_9_1" | "latest"=> main_4_9_1(), 102 | // #[cfg(feature = "chapter-4")] "4_9_2" | "latest"=> main_4_9_2(), 103 | // #[cfg(feature = "chapter-4")] "4_9_3" | "latest"=> main_4_9_3(), 104 | // #[cfg(feature = "chapter-4")] "4_10_1" | "latest"=> main_4_10_1(), 105 | // #[cfg(feature = "chapter-4")] "4_10_2" | "latest"=> main_4_10_2(), 106 | // #[cfg(feature = "chapter-4")] "4_10_3" | "latest"=> main_4_10_3(), 107 | // #[cfg(feature = "chapter-4")] "4_11" | "latest"=> main_4_11(), 108 | 109 | // #[cfg(feature = "chapter-5")] "5_1" | "latest"=> main_5_1(), 110 | // #[cfg(feature = "chapter-5")] "5_2" | "latest"=> main_5_2(), 111 | // #[cfg(feature = "chapter-5")] "5_4" | "latest"=> main_5_4(), 112 | // #[cfg(feature = "chapter-5")] "5_6" | "latest"=> main_5_6(), 113 | 114 | // #[cfg(feature = "chapter-6")] "6_1_1" | "latest"=> main_6_1_1(), 115 | // #[cfg(feature = "chapter-6")] "6_1_2" | "latest"=> main_6_1_2(), 116 | 117 | #[cfg(feature = "chapter-7")] "7_1" => main_7_1(), 118 | #[cfg(feature = "chapter-7")] "7_2" => main_7_2(), 119 | //#[cfg(feature = "chapter-7")] "7_2" | "latest"=> main_7_2(), 120 | 121 | _ => println!("Unknown tutorial id") 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/mesh.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use std::rc::Rc; 3 | use crate::texture; 4 | use crate::shader::Shader; 5 | extern crate nalgebra_glm as glm; 6 | 7 | pub enum MeshTexture { 8 | DiffuseMap(Rc), 9 | SpecularMap(Rc), 10 | NormalMap(Rc), 11 | } 12 | 13 | pub struct Mesh { 14 | gl : Rc, 15 | 16 | // Render data 17 | vao: Option, 18 | vbo_p: Option, 19 | vbo_n: Option, 20 | vbo_t: Option, 21 | ebo: Option, 22 | textures: Vec, 23 | num_indices : usize, 24 | num_vertices : usize, 25 | } 26 | 27 | impl Mesh { 28 | 29 | pub fn new( 30 | gl : Rc, 31 | positions: &[f32], 32 | normals: &[f32], 33 | tex_coords: &[f32], 34 | indices: &[u32], 35 | textures: Vec ) -> Self { 36 | 37 | unsafe { 38 | // Create buffer 39 | let vao = Some( gl.create_vertex_array().expect("Create VAO")); 40 | let vbo_p = Some( gl.create_buffer().expect("Create VBO")); 41 | let vbo_n = Some( gl.create_buffer().expect("Create VBO")); 42 | let vbo_t = Some( gl.create_buffer().expect("Create VBO")); 43 | let ebo = Some( gl.create_buffer().expect("Create EBO")); 44 | 45 | gl.bind_vertex_array( vao ); 46 | 47 | // load positions 48 | gl.bind_buffer(glow::ARRAY_BUFFER, vbo_p ); 49 | let u8_buffer = bytemuck::cast_slice(&positions); 50 | // println!("Vertices {} Indices {}", positions.len(), indices.len()); 51 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 52 | 53 | gl.vertex_attrib_pointer_f32( 54 | 0, 55 | 3, 56 | glow::FLOAT, 57 | false, 58 | 0, 59 | 0); 60 | gl.enable_vertex_attrib_array(0); 61 | 62 | // load normals 63 | gl.bind_buffer(glow::ARRAY_BUFFER, vbo_n ); 64 | let u8_buffer = bytemuck::cast_slice(&normals); 65 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 66 | 67 | gl.vertex_attrib_pointer_f32( 68 | 1, 69 | 3, 70 | glow::FLOAT, 71 | false, 72 | 0, 73 | 0); 74 | gl.enable_vertex_attrib_array(1); 75 | 76 | // tex coord normals 77 | gl.bind_buffer(glow::ARRAY_BUFFER, vbo_t); 78 | let u8_buffer = bytemuck::cast_slice(&tex_coords); 79 | gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 80 | 81 | gl.vertex_attrib_pointer_f32( 82 | 2, 83 | 2, 84 | glow::FLOAT, 85 | false, 86 | 0, 87 | 0); 88 | gl.enable_vertex_attrib_array(2); 89 | 90 | gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, ebo); 91 | let u8_buffer = bytemuck::cast_slice(&indices); 92 | gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, u8_buffer, glow::STATIC_DRAW); 93 | 94 | gl.bind_vertex_array( None ); 95 | 96 | Self { 97 | gl, 98 | vao, 99 | vbo_p, 100 | vbo_n, 101 | vbo_t, 102 | ebo, 103 | textures, 104 | num_indices : indices.len(), 105 | num_vertices : positions.len(), 106 | } 107 | } 108 | } 109 | 110 | /// render the mesh 111 | pub fn draw(&self, shader :&Shader) { 112 | unsafe { 113 | // bind vao 114 | self.gl.bind_vertex_array(self.vao); 115 | 116 | let mut diffuse_id = 0; 117 | let mut specular_id = 0; 118 | let mut normal_id = 0; 119 | 120 | // set textures 121 | for (idx, mesh_texture) in self.textures.iter().enumerate() { 122 | let (texture,field) = match mesh_texture { 123 | MeshTexture::DiffuseMap(texture) => { 124 | diffuse_id += 1; 125 | (texture, format!("texture_diffuse{}", diffuse_id) ) 126 | } 127 | MeshTexture::SpecularMap(texture) => { 128 | specular_id += 1; 129 | (texture, format!("texture_specular{}", specular_id)) 130 | } 131 | MeshTexture::NormalMap(texture) => { 132 | normal_id += 1; 133 | (texture, format!("texture_normal{}", normal_id)) 134 | } 135 | }; 136 | //println!("Set mesh texture {} to {}", &field, idx); 137 | self.gl.active_texture(glow::TEXTURE0 + idx as u32); 138 | shader.set_uniform_i32(&field, idx as i32); 139 | texture.bind(); 140 | } 141 | 142 | if self.num_indices > 0 { 143 | self.gl.draw_elements( 144 | glow::TRIANGLES, 145 | self.num_indices as i32, 146 | glow::UNSIGNED_INT, 147 | 0); 148 | } else { 149 | self.gl.draw_arrays(glow::TRIANGLES, 0, self.num_vertices as i32 / 3); 150 | } 151 | 152 | self.gl.bind_vertex_array(None); 153 | } 154 | } 155 | } 156 | 157 | 158 | impl Drop for Mesh { 159 | fn drop(&mut self) { 160 | unsafe { 161 | if let Some(id) = self.vbo_p {self.gl.delete_buffer(id);} 162 | if let Some(id) = self.vbo_n {self.gl.delete_buffer(id);} 163 | if let Some(id) = self.vbo_t {self.gl.delete_buffer(id);} 164 | if let Some(id) = self.ebo {self.gl.delete_buffer(id);} 165 | if let Some(id) = self.vao {self.gl.delete_vertex_array(id);} 166 | 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/mesh_cube.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::rc::Rc; 3 | use crate::mesh::Mesh; 4 | extern crate nalgebra_glm as glm; 5 | 6 | pub fn new(gl : Rc,size: f32, ) -> Mesh { 7 | 8 | let hs = size / 2.0; 9 | 10 | let positions: [f32; 108] = [ 11 | -hs, -hs, -hs, 12 | hs, -hs, -hs, 13 | hs, hs, -hs, 14 | hs, hs, -hs, 15 | -hs, hs, -hs, 16 | -hs, -hs, -hs, 17 | 18 | -hs, -hs, hs, 19 | hs, -hs, hs, 20 | hs, hs, hs, 21 | hs, hs, hs, 22 | -hs, hs, hs, 23 | -hs, -hs, hs, 24 | 25 | -hs, hs, hs, 26 | -hs, hs, -hs, 27 | -hs, -hs, -hs, 28 | -hs, -hs, -hs, 29 | -hs, -hs, hs, 30 | -hs, hs, hs, 31 | 32 | hs, hs, hs, 33 | hs, hs, -hs, 34 | hs, -hs, -hs, 35 | hs, -hs, -hs, 36 | hs, -hs, hs, 37 | hs, hs, hs, 38 | 39 | -hs, -hs, -hs, 40 | hs, -hs, -hs, 41 | hs, -hs, hs, 42 | hs, -hs, hs, 43 | -hs, -hs, hs, 44 | -hs, -hs, -hs, 45 | 46 | -hs, hs, -hs, 47 | hs, hs, -hs, 48 | hs, hs, hs, 49 | hs, hs, hs, 50 | -hs, hs, hs, 51 | -hs, hs, -hs]; 52 | 53 | let normals: [f32; 108] = [ 54 | 0.0, 0.0, -1.0, 55 | 0.0, 0.0, -1.0, 56 | 0.0, 0.0, -1.0, 57 | 0.0, 0.0, -1.0, 58 | 0.0, 0.0, -1.0, 59 | 0.0, 0.0, -1.0, 60 | 61 | 0.0, 0.0, 1.0, 62 | 0.0, 0.0, 1.0, 63 | 0.0, 0.0, 1.0, 64 | 0.0, 0.0, 1.0, 65 | 0.0, 0.0, 1.0, 66 | 0.0, 0.0, 1.0, 67 | 68 | 1.0, 0.0, 0.0, 69 | 1.0, 0.0, 0.0, 70 | 1.0, 0.0, 0.0, 71 | 1.0, 0.0, 0.0, 72 | 1.0, 0.0, 0.0, 73 | 1.0, 0.0, 0.0, 74 | 75 | 1.0, 0.0, 0.0, 76 | 1.0, 0.0, 0.0, 77 | 1.0, 0.0, 0.0, 78 | 1.0, 0.0, 0.0, 79 | 1.0, 0.0, 0.0, 80 | 1.0, 0.0, 0.0, 81 | 82 | 0.0, -1.0, 0.0, 83 | 0.0, -1.0, 0.0, 84 | 0.0, -1.0, 0.0, 85 | 0.0, -1.0, 0.0, 86 | 0.0, -1.0, 0.0, 87 | 0.0, -1.0, 0.0, 88 | 89 | 0.0, 1.0, 0.0, 90 | 0.0, 1.0, 0.0, 91 | 0.0, 1.0, 0.0, 92 | 0.0, 1.0, 0.0, 93 | 0.0, 1.0, 0.0, 94 | 0.0, 1.0, 0.0 ]; 95 | 96 | let tex_coords: [f32; 72] = [ 97 | 0.0, 0.0, 98 | 1.0, 0.0, 99 | 1.0, 1.0, 100 | 1.0, 1.0, 101 | 0.0, 1.0, 102 | 0.0, 0.0, 103 | 104 | 0.0, 0.0, 105 | 1.0, 0.0, 106 | 1.0, 1.0, 107 | 1.0, 1.0, 108 | 0.0, 1.0, 109 | 0.0, 0.0, 110 | 111 | 1.0, 0.0, 112 | 1.0, 1.0, 113 | 0.0, 1.0, 114 | 0.0, 1.0, 115 | 0.0, 0.0, 116 | 1.0, 0.0, 117 | 118 | 1.0, 0.0, 119 | 1.0, 1.0, 120 | 0.0, 1.0, 121 | 0.0, 1.0, 122 | 0.0, 0.0, 123 | 1.0, 0.0, 124 | 125 | 0.0, 1.0, 126 | 1.0, 1.0, 127 | 1.0, 0.0, 128 | 1.0, 0.0, 129 | 0.0, 0.0, 130 | 0.0, 1.0, 131 | 132 | 0.0, 1.0, 133 | 1.0, 1.0, 134 | 1.0, 0.0, 135 | 1.0, 0.0, 136 | 0.0, 0.0, 137 | 0.0, 1.0]; 138 | 139 | let indices = []; 140 | Mesh::new( gl, &positions, &normals, &tex_coords, &indices, Vec::new()) 141 | } 142 | 143 | -------------------------------------------------------------------------------- /src/model.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Drop; 2 | use std::path::Path; 3 | use std::rc::Rc; 4 | use std::collections::HashMap; 5 | 6 | use crate::{mesh::{Mesh, MeshTexture}, shader::Shader, texture::Texture}; 7 | use tobj; 8 | 9 | pub struct TexturePool { 10 | gl : Rc, 11 | texture_pool : HashMap>, 12 | } 13 | 14 | impl TexturePool { 15 | pub fn new(gl : Rc) -> Self { 16 | Self { 17 | gl, 18 | texture_pool : HashMap::new(), 19 | } 20 | } 21 | 22 | pub fn load_texture(&mut self, filename :&str) ->Rc { 23 | if let Some(rc_texture) = self.texture_pool.get(filename.into()) { 24 | return rc_texture.clone(); 25 | } 26 | let rc_texture = Rc::new( Texture::new(self.gl.clone(), &filename,true)); 27 | self.texture_pool.insert(filename.into(), rc_texture.clone()); 28 | return rc_texture; 29 | } 30 | } 31 | 32 | pub struct Model { 33 | meshes : Vec, 34 | } 35 | 36 | impl Model { 37 | /// constructor, expects a filepath to a 3D model. 38 | pub fn new( gl : Rc, path: &str) -> Self { 39 | 40 | let mut meshes = Vec::new(); 41 | let mut texture_pool = TexturePool::new(gl.clone()); 42 | 43 | let path = Path::new(path); 44 | 45 | // retrieve the directory path of the filepath 46 | let directory : String = path.parent().unwrap_or_else(|| Path::new("")).to_str().unwrap().into(); 47 | let mut load_options = tobj::LoadOptions::default(); 48 | load_options.triangulate = true; 49 | load_options.single_index = true; 50 | 51 | let obj = tobj::load_obj(path, &load_options); 52 | 53 | let (models, materials_result) = obj.unwrap(); 54 | 55 | for model in models.into_iter(){ 56 | 57 | let mesh = &model.mesh; 58 | 59 | let mut textures:Vec= Vec::new(); 60 | 61 | if let Some(material_id) = mesh.material_id { 62 | if let Ok(materials) = &materials_result { 63 | let material = &materials[material_id]; 64 | if let Some( diffuse ) = &material.diffuse_texture { 65 | println!("material.diffuse_texture {}", diffuse); 66 | let filename = format!("{}/{}", &directory, diffuse); 67 | let rc_texture = texture_pool.load_texture(&filename); 68 | textures.push( MeshTexture::DiffuseMap( rc_texture )); 69 | } 70 | if let Some( specular ) = &material.specular_texture { 71 | println!("material.normal_texture {}", specular); 72 | let filename = format!("{}/{}", &directory, specular); 73 | let rc_texture = texture_pool.load_texture(&filename); 74 | textures.push( MeshTexture::SpecularMap( rc_texture )); 75 | } 76 | 77 | if let Some( normal ) = &material.normal_texture { 78 | println!("material.normal_texture {}", normal); 79 | let filename = format!("{}/{}", &directory, normal); 80 | let rc_texture = texture_pool.load_texture(&filename); 81 | textures.push( MeshTexture::NormalMap( rc_texture )); 82 | } 83 | } 84 | } 85 | 86 | // println!("POSITIONS"); 87 | // for (idx, tc) in mesh.positions.iter().enumerate() { 88 | // if idx%3 == 0 { 89 | // print!("\npos: {} ", idx); 90 | // } 91 | // print!(" {}", tc ); 92 | // } 93 | 94 | // println!("TEXCOORDS"); 95 | // for (idx, tc) in mesh.texcoords.iter().enumerate() { 96 | // if idx%2 == 0 { 97 | // print!("\nTEX: {} ", idx); 98 | // } 99 | // print!(" {}", tc ); 100 | // } 101 | 102 | // println!("INDICES"); 103 | // for idx in mesh.indices.iter() { 104 | // print!(" {}", idx ); 105 | // } 106 | 107 | let new_mesh = Mesh::new( 108 | gl.clone(), 109 | &mesh.positions, 110 | &mesh.normals, 111 | &mesh.texcoords, 112 | &mesh.indices, 113 | textures); 114 | 115 | meshes.push(new_mesh); 116 | } 117 | 118 | Self { 119 | meshes, 120 | } 121 | } 122 | pub fn draw(&self, shader: &Shader) { 123 | for mesh in &self.meshes { 124 | mesh.draw(shader); 125 | } 126 | } 127 | } 128 | 129 | impl Drop for Model { 130 | fn drop(&mut self) { 131 | 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/texture.rs: -------------------------------------------------------------------------------- 1 | use glow::*; 2 | use std::ops::Drop; 3 | use std::rc::Rc; 4 | 5 | 6 | #[derive(Debug)] 7 | pub struct Texture { 8 | gl : Rc, 9 | texture: glow::Texture, 10 | } 11 | 12 | impl Texture { 13 | pub fn new( gl : Rc, img_file_name :&str, vflip : bool ) ->Self { 14 | 15 | let texture = unsafe { 16 | // load and create a texture 17 | // ------------------------- 18 | let texture = gl.create_texture().expect("Create a texture" ); 19 | 20 | // bind texture, all upcoming GL_TEXTURE_2D operations now have effect on this texture object 21 | gl.bind_texture(glow::TEXTURE_2D, Some(texture)); 22 | 23 | // set the texture wrapping & repeat parameters 24 | gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32); 25 | gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::REPEAT as i32); 26 | 27 | // set texture filtering parameters 28 | gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::LINEAR as i32); 29 | gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::LINEAR as i32); 30 | 31 | // load image, create texture and generate mipmaps 32 | println!("Loading image: {}", img_file_name); 33 | 34 | let img = if vflip { 35 | image::open(img_file_name).unwrap().flipv().into_rgba8() 36 | } else { 37 | image::open(img_file_name).unwrap().into_rgba8() 38 | }; 39 | 40 | 41 | //let img = image::open(img_file_name).unwrap().into_rgba8(); 42 | 43 | println!("Loading done .. "); 44 | let (img_w, img_h) = img.dimensions(); 45 | let raw_img = img.into_raw(); 46 | 47 | // Give the image to OpenGL 48 | gl.tex_image_2d(glow::TEXTURE_2D, 49 | 0, 50 | glow::RGBA as i32, 51 | img_w as i32, 52 | img_h as i32, 53 | 0, 54 | glow::RGBA, 55 | glow::UNSIGNED_BYTE, 56 | Some(&raw_img) ); 57 | 58 | gl.generate_mipmap(glow::TEXTURE_2D); 59 | texture 60 | }; 61 | Self { 62 | gl, 63 | texture, 64 | } 65 | } 66 | 67 | pub fn set_wrapping(&mut self, repeat_s: u32, repeat_t: u32 ) { 68 | self.bind(); 69 | unsafe { 70 | self.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, repeat_s as i32); 71 | self.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, repeat_t as i32); 72 | } 73 | } 74 | 75 | 76 | pub fn bind(&self) { 77 | unsafe { 78 | self.gl.bind_texture(glow::TEXTURE_2D, Some(self.texture)); 79 | } 80 | } 81 | } 82 | 83 | 84 | impl Drop for Texture { 85 | fn drop(&mut self) { 86 | unsafe { 87 | self.gl.delete_texture(self.texture); 88 | } 89 | } 90 | } 91 | --------------------------------------------------------------------------------