├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── requirements.txt ├── resources ├── objects │ ├── 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 │ │ ├── planet.mtl │ │ ├── planet.obj │ │ └── planet_Quom1200.png │ └── rock │ │ ├── rock.mtl │ │ ├── rock.obj │ │ └── rock.png └── textures │ ├── awesomeface.png │ ├── bricks2.jpg │ ├── bricks2_disp.jpg │ ├── bricks2_normal.jpg │ ├── brickwall.jpg │ ├── brickwall_normal.jpg │ ├── container.jpg │ ├── container2.png │ ├── container2_specular.png │ ├── grass.png │ ├── hdr │ └── newport_loft.hdr │ ├── marble.jpg │ ├── matrix.jpg │ ├── metal.png │ ├── pbr │ ├── gold │ │ ├── albedo.png │ │ ├── ao.png │ │ ├── metallic.png │ │ ├── normal.png │ │ └── roughness.png │ ├── grass │ │ ├── albedo.png │ │ ├── ao.png │ │ ├── metallic.png │ │ ├── normal.png │ │ └── roughness.png │ ├── plastic │ │ ├── albedo.png │ │ ├── ao.png │ │ ├── metallic.png │ │ ├── normal.png │ │ └── roughness.png │ ├── rusted_iron │ │ ├── albedo.png │ │ ├── ao.png │ │ ├── metallic.png │ │ ├── normal.png │ │ └── roughness.png │ └── wall │ │ ├── albedo.png │ │ ├── ao.png │ │ ├── metallic.png │ │ ├── normal.png │ │ └── roughness.png │ ├── skybox │ ├── back.jpg │ ├── bottom.jpg │ ├── front.jpg │ ├── left.jpg │ ├── right.jpg │ └── top.jpg │ ├── toy_box_diffuse.png │ ├── toy_box_disp.png │ ├── toy_box_normal.png │ ├── window.png │ └── wood.png └── source ├── 1.getting_started ├── 1.1.hello_window.py ├── 1.2.hello_window_clear.py ├── 2.1.hello_triangle.py ├── 2.2.hello_triangle_indexed.py ├── 2.3.hello_triangle_exercise1.py ├── 2.3.hello_triangle_exercise2.py ├── 2.3.hello_triangle_exercise3.py ├── 3.1.shaders_uniform.py ├── 3.2.shaders_interpolation.py ├── 3.3.shaders_class.py ├── 3.4.shaders_exercise1.py ├── 3.5.shaders_exercise2.py ├── 3.6.shaders_exercise3.py ├── 4.1.textures.py ├── 4.2.textures_combined.py ├── 4.3.textures_exercise1.py ├── 4.4.textures_exercise2.py ├── 4.5.textures_exercise3.py ├── 4.6.textures_exercise4.py ├── 5.1.transformations.py ├── 5.2.transformation_exercise2.py ├── 6.1.coordinate_systems.py ├── 6.2.coordinate_systems_depth.py ├── 6.3.coordinate_systems_multiple.py ├── 6.4.coordinate_systems_exercise1.py ├── 7.1.camera_circle.py ├── 7.2.camera_keyboard_dt.py ├── 7.3.camera_mouse_zoom.py ├── 7.4.camera_class.py └── shaders │ ├── 3.3.shader.fs │ ├── 3.3.shader.vs │ ├── 3.4.shader.fs │ ├── 3.4.shader.vs │ ├── 3.5.shader.fs │ ├── 3.5.shader.vs │ ├── 3.6.shader.fs │ ├── 3.6.shader.vs │ ├── 4.1.texture.fs │ ├── 4.1.texture.vs │ ├── 4.1.texture_mix.fs │ ├── 4.2.texture.fs │ ├── 4.2.texture.vs │ ├── 4.3.texture_exercise1.fs │ ├── 4.3.texture_exercise1.vs │ ├── 4.6.texture_exercise4.fs │ ├── 4.6.texture_exercise4.vs │ ├── 5.1.transform.fs │ ├── 5.1.transform.vs │ ├── 6.1.coordinate_systems.fs │ ├── 6.1.coordinate_systems.vs │ ├── 7.1.camera.fs │ └── 7.1.camera.vs ├── 2.lighting ├── 1.colors.py ├── 2.1.basic_lighting_diffuse.py ├── 2.2.basic_lighting_specular.py ├── 3.1.materials.py ├── 3.2.materials_exercise1.py ├── 4.1.lighting_maps_diffuse_map.py ├── 4.2.lighting_maps_specular_map.py ├── 4.3.lighting_maps_exercise4.py ├── 5.1.light_casters_directional.py ├── 5.2.light_casters_point.py ├── 5.3.light_casters_spot.py ├── 5.4.light_casters_spot_soft.py ├── 6.1.multiple_lights_excercise1.py ├── 6.multiple_lights.py └── shaders │ ├── 1.colors.fs │ ├── 1.colors.vs │ ├── 1.lamp.fs │ ├── 1.lamp.vs │ ├── 2.1.basic_lighting.fs │ ├── 2.1.basic_lighting.vs │ ├── 2.2.basic_lighting.fs │ ├── 2.2.basic_lighting.vs │ ├── 3.1.materials.fs │ ├── 3.1.materials.vs │ ├── 4.1.lighting_maps.fs │ ├── 4.1.lighting_maps.vs │ ├── 4.2.lighting_maps.fs │ ├── 4.2.lighting_maps.vs │ ├── 4.3.lighting_maps.fs │ ├── 4.3.lighting_maps.vs │ ├── 5.1.light_casters.fs │ ├── 5.1.light_casters.vs │ ├── 5.2.light_casters.fs │ ├── 5.2.light_casters.vs │ ├── 5.3.light_casters.fs │ ├── 5.3.light_casters.vs │ ├── 5.4.light_casters.fs │ ├── 5.4.light_casters.vs │ ├── 6.1.lamp.fs │ ├── 6.multiple_lights.fs │ └── 6.multiple_lights.vs ├── 3.model_loading ├── 1.model_loading.py └── shaders │ ├── model_loading.fs │ └── model_loading.vs ├── 4.advanced_opengl ├── 1.1.depth_testing.py └── shaders │ ├── 1.1.depth_testing.fs │ └── 1.1.depth_testing.vs ├── __init__.py ├── camera.py ├── mesh.py ├── model.py ├── shader.py ├── texture.py └── window.py /.gitattributes: -------------------------------------------------------------------------------- 1 | *.py linguist-detectable=true 2 | *.cpp linguist-detectable=false 3 | *.h linguist-detectable=false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-project 2 | *.sublime-workspace 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | .pytest_cache/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | db.sqlite3 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # SageMath parsed files 83 | *.sage.py 84 | 85 | # Environments 86 | .env 87 | .venv 88 | env/ 89 | venv/ 90 | ENV/ 91 | env.bak/ 92 | venv.bak/ 93 | 94 | # Spyder project settings 95 | .spyderproject 96 | .spyproject 97 | 98 | # Rope project settings 99 | .ropeproject 100 | 101 | # mkdocs documentation 102 | /site 103 | 104 | # mypy 105 | .mypy_cache/ 106 | 107 | # cython generated files 108 | source/assimp/*.cpp -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Ian Karanja 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 | # learnopengl-python 2 | Python port for https://learnopengl.com/ 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | assimp-py==1.0.7 2 | glfw==2.5.5 3 | multipledispatch==0.6.0 4 | numpy==1.24.1 5 | Pillow==9.3.0 6 | PyOpenGL==3.1.6 7 | pyrr==0.10.3 8 | six==1.16.0 9 | -------------------------------------------------------------------------------- /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/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/cyborg/cyborg.blend -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg.blend1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/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/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/cyborg/cyborg_diffuse.png -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/cyborg/cyborg_normal.png -------------------------------------------------------------------------------- /resources/objects/cyborg/cyborg_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/cyborg/cyborg_specular.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/arm_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/arm_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/arm_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/arm_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/arm_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/arm_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/arm_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/arm_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/back.jpg -------------------------------------------------------------------------------- /resources/objects/nanosuit/body_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/body_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/body_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/body_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/body_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/body_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/body_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/body_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_arm_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/cell_arm_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_body_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/cell_body_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/cell_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_hand_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/cell_hand_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_helmet_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/cell_helmet_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/cell_leg_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/cell_leg_alpha.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/front.jpg -------------------------------------------------------------------------------- /resources/objects/nanosuit/glass_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/glass_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/glass_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/glass_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/glass_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/glass_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/hand_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/hand_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/hand_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/hand_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/hand_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/hand_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/hand_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/hand_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/helmet_diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/helmet_diff.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/helmet_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/helmet_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/helmet_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/helmet_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/helmet_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/helmet_showroom_spec.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/leg_dif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/leg_dif.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/leg_showroom_ddn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/leg_showroom_ddn.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/leg_showroom_refl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/nanosuit/leg_showroom_refl.png -------------------------------------------------------------------------------- /resources/objects/nanosuit/leg_showroom_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/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/planet.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL 2 | # Material Count: 1 3 | 4 | newmtl Material.001 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.087302 0.087302 0.087302 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | map_Kd planet_Quom1200.png 13 | map_Bump planet_Quom1200.png 14 | -------------------------------------------------------------------------------- /resources/objects/planet/planet_Quom1200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/planet/planet_Quom1200.png -------------------------------------------------------------------------------- /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_Kd rock.png 13 | map_Bump rock.png 14 | -------------------------------------------------------------------------------- /resources/objects/rock/rock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/objects/rock/rock.png -------------------------------------------------------------------------------- /resources/textures/awesomeface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/awesomeface.png -------------------------------------------------------------------------------- /resources/textures/bricks2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/bricks2.jpg -------------------------------------------------------------------------------- /resources/textures/bricks2_disp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/bricks2_disp.jpg -------------------------------------------------------------------------------- /resources/textures/bricks2_normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/bricks2_normal.jpg -------------------------------------------------------------------------------- /resources/textures/brickwall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/brickwall.jpg -------------------------------------------------------------------------------- /resources/textures/brickwall_normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/brickwall_normal.jpg -------------------------------------------------------------------------------- /resources/textures/container.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/container.jpg -------------------------------------------------------------------------------- /resources/textures/container2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/container2.png -------------------------------------------------------------------------------- /resources/textures/container2_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/container2_specular.png -------------------------------------------------------------------------------- /resources/textures/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/grass.png -------------------------------------------------------------------------------- /resources/textures/hdr/newport_loft.hdr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/hdr/newport_loft.hdr -------------------------------------------------------------------------------- /resources/textures/marble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/marble.jpg -------------------------------------------------------------------------------- /resources/textures/matrix.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/matrix.jpg -------------------------------------------------------------------------------- /resources/textures/metal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/metal.png -------------------------------------------------------------------------------- /resources/textures/pbr/gold/albedo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/gold/albedo.png -------------------------------------------------------------------------------- /resources/textures/pbr/gold/ao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/gold/ao.png -------------------------------------------------------------------------------- /resources/textures/pbr/gold/metallic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/gold/metallic.png -------------------------------------------------------------------------------- /resources/textures/pbr/gold/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/gold/normal.png -------------------------------------------------------------------------------- /resources/textures/pbr/gold/roughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/gold/roughness.png -------------------------------------------------------------------------------- /resources/textures/pbr/grass/albedo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/grass/albedo.png -------------------------------------------------------------------------------- /resources/textures/pbr/grass/ao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/grass/ao.png -------------------------------------------------------------------------------- /resources/textures/pbr/grass/metallic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/grass/metallic.png -------------------------------------------------------------------------------- /resources/textures/pbr/grass/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/grass/normal.png -------------------------------------------------------------------------------- /resources/textures/pbr/grass/roughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/grass/roughness.png -------------------------------------------------------------------------------- /resources/textures/pbr/plastic/albedo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/plastic/albedo.png -------------------------------------------------------------------------------- /resources/textures/pbr/plastic/ao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/plastic/ao.png -------------------------------------------------------------------------------- /resources/textures/pbr/plastic/metallic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/plastic/metallic.png -------------------------------------------------------------------------------- /resources/textures/pbr/plastic/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/plastic/normal.png -------------------------------------------------------------------------------- /resources/textures/pbr/plastic/roughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/plastic/roughness.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/albedo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/rusted_iron/albedo.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/ao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/rusted_iron/ao.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/metallic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/rusted_iron/metallic.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/rusted_iron/normal.png -------------------------------------------------------------------------------- /resources/textures/pbr/rusted_iron/roughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/rusted_iron/roughness.png -------------------------------------------------------------------------------- /resources/textures/pbr/wall/albedo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/wall/albedo.png -------------------------------------------------------------------------------- /resources/textures/pbr/wall/ao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/wall/ao.png -------------------------------------------------------------------------------- /resources/textures/pbr/wall/metallic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/wall/metallic.png -------------------------------------------------------------------------------- /resources/textures/pbr/wall/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/wall/normal.png -------------------------------------------------------------------------------- /resources/textures/pbr/wall/roughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/pbr/wall/roughness.png -------------------------------------------------------------------------------- /resources/textures/skybox/back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/skybox/back.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/skybox/bottom.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/skybox/front.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/left.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/skybox/left.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/right.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/skybox/right.jpg -------------------------------------------------------------------------------- /resources/textures/skybox/top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/skybox/top.jpg -------------------------------------------------------------------------------- /resources/textures/toy_box_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/toy_box_diffuse.png -------------------------------------------------------------------------------- /resources/textures/toy_box_disp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/toy_box_disp.png -------------------------------------------------------------------------------- /resources/textures/toy_box_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/toy_box_normal.png -------------------------------------------------------------------------------- /resources/textures/window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/window.png -------------------------------------------------------------------------------- /resources/textures/wood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/resources/textures/wood.png -------------------------------------------------------------------------------- /source/1.getting_started/1.1.hello_window.py: -------------------------------------------------------------------------------- 1 | import glfw 2 | import OpenGL.GL as gl 3 | 4 | 5 | def main(): 6 | glfw.init() 7 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 8 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 9 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 10 | 11 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 12 | if not window: 13 | print("Window Creation failed!") 14 | glfw.terminate() 15 | 16 | glfw.make_context_current(window) 17 | glfw.set_window_size_callback(window, on_resize) 18 | 19 | while not glfw.window_should_close(window): 20 | process_input(window) 21 | 22 | glfw.poll_events() 23 | glfw.swap_buffers(window) 24 | 25 | glfw.terminate() 26 | 27 | 28 | def on_resize(window, w, h): 29 | gl.glViewport(0, 0, w, h) 30 | 31 | 32 | def process_input(window): 33 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 34 | glfw.set_window_should_close(window, True) 35 | 36 | 37 | if __name__ == '__main__': 38 | main() 39 | -------------------------------------------------------------------------------- /source/1.getting_started/1.2.hello_window_clear.py: -------------------------------------------------------------------------------- 1 | import glfw 2 | import OpenGL.GL as gl 3 | 4 | 5 | def main(): 6 | glfw.init() 7 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 8 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 9 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 10 | 11 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 12 | if not window: 13 | print("Window Creation failed!") 14 | glfw.terminate() 15 | 16 | glfw.make_context_current(window) 17 | glfw.set_window_size_callback(window, on_resize) 18 | 19 | while not glfw.window_should_close(window): 20 | process_input(window) 21 | 22 | gl.glClearColor(.2, .3, .3, 1.0) 23 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 24 | 25 | glfw.poll_events() 26 | glfw.swap_buffers(window) 27 | 28 | glfw.terminate() 29 | 30 | 31 | def on_resize(window, w, h): 32 | gl.glViewport(0, 0, w, h) 33 | 34 | 35 | def process_input(window): 36 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 37 | glfw.set_window_should_close(window, True) 38 | 39 | 40 | if __name__ == '__main__': 41 | main() 42 | -------------------------------------------------------------------------------- /source/1.getting_started/2.1.hello_triangle.py: -------------------------------------------------------------------------------- 1 | import glfw 2 | import OpenGL.GL as gl 3 | from OpenGL.GL import shaders 4 | from ctypes import c_float, sizeof, c_void_p 5 | 6 | 7 | vertex_shader = """ 8 | #version 330 core 9 | 10 | layout (location = 0) in vec3 aPos; 11 | 12 | void main() { 13 | gl_Position = vec4(aPos, 1.0); 14 | } 15 | """ 16 | 17 | fragment_shader = """ 18 | #version 330 core 19 | 20 | out vec4 FragColor; 21 | 22 | void main() { 23 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 24 | } 25 | """ 26 | 27 | 28 | def main(): 29 | glfw.init() 30 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 31 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 32 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 33 | 34 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 35 | if not window: 36 | print("Window Creation failed!") 37 | glfw.terminate() 38 | 39 | glfw.make_context_current(window) 40 | glfw.set_window_size_callback(window, on_resize) 41 | 42 | shader = shaders.compileProgram( 43 | shaders.compileShader(vertex_shader, gl.GL_VERTEX_SHADER), 44 | shaders.compileShader(fragment_shader, gl.GL_FRAGMENT_SHADER), 45 | ) 46 | 47 | vertices = [ 48 | -0.5, -0.5, 0.0, 49 | 0.5, -0.5, 0.0, 50 | 0.0, 0.5, 0.0, 51 | ] 52 | vertices = (c_float * len(vertices))(*vertices) 53 | 54 | vao = gl.glGenVertexArrays(1) 55 | gl.glBindVertexArray(vao) 56 | 57 | vbo = gl.glGenBuffers(1) 58 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 59 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 60 | 61 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 62 | gl.glEnableVertexAttribArray(0) 63 | 64 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) 65 | gl.glBindVertexArray(0) 66 | 67 | while not glfw.window_should_close(window): 68 | process_input(window) 69 | 70 | gl.glClearColor(.2, .3, .3, 1.0) 71 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 72 | 73 | gl.glUseProgram(shader) 74 | gl.glBindVertexArray(vao) 75 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 76 | 77 | glfw.poll_events() 78 | glfw.swap_buffers(window) 79 | 80 | gl.glDeleteVertexArrays(1, id(vao)) 81 | gl.glDeleteBuffers(1, id(vbo)) 82 | glfw.terminate() 83 | 84 | 85 | def on_resize(window, w, h): 86 | gl.glViewport(0, 0, w, h) 87 | 88 | 89 | def process_input(window): 90 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 91 | glfw.set_window_should_close(window, True) 92 | 93 | 94 | if __name__ == '__main__': 95 | main() 96 | -------------------------------------------------------------------------------- /source/1.getting_started/2.2.hello_triangle_indexed.py: -------------------------------------------------------------------------------- 1 | import glfw 2 | import OpenGL.GL as gl 3 | from OpenGL.GL import shaders 4 | from ctypes import c_uint, c_float, sizeof, c_void_p 5 | 6 | vertex_shader = """ 7 | #version 330 core 8 | 9 | layout (location = 0) in vec3 aPos; 10 | 11 | void main() { 12 | gl_Position = vec4(aPos, 1.0); 13 | } 14 | """ 15 | 16 | fragment_shader = """ 17 | #version 330 core 18 | 19 | out vec4 FragColor; 20 | 21 | void main() { 22 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 23 | } 24 | """ 25 | 26 | 27 | def main(): 28 | glfw.init() 29 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 30 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 31 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 32 | 33 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 34 | if not window: 35 | print("Window Creation failed!") 36 | glfw.terminate() 37 | 38 | glfw.make_context_current(window) 39 | glfw.set_window_size_callback(window, on_resize) 40 | 41 | shader = shaders.compileProgram( 42 | shaders.compileShader(vertex_shader, gl.GL_VERTEX_SHADER), 43 | shaders.compileShader(fragment_shader, gl.GL_FRAGMENT_SHADER), 44 | ) 45 | 46 | vertices = [ 47 | 0.5, 0.5, 0.0, # top right 48 | 0.5, -0.5, 0.0, # bottom right 49 | -0.5, -0.5, 0.0, # bottom left 50 | -0.5, 0.5, 0.0 # top left 51 | ] 52 | vertices = (c_float * len(vertices))(*vertices) 53 | 54 | indices = [ 55 | 0, 1, 3, 56 | 1, 2, 3 57 | ] 58 | indices = (c_uint * len(indices))(*indices) 59 | 60 | vao = gl.glGenVertexArrays(1) 61 | gl.glBindVertexArray(vao) 62 | 63 | vbo = gl.glGenBuffers(1) 64 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 65 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 66 | 67 | ebo = gl.glGenBuffers(1) 68 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 69 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 70 | 71 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 72 | gl.glEnableVertexAttribArray(0) 73 | 74 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) 75 | gl.glBindVertexArray(0) 76 | 77 | # -- uncomment to draw wireframe 78 | # gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) 79 | 80 | while not glfw.window_should_close(window): 81 | process_input(window) 82 | 83 | gl.glClearColor(.2, .3, .3, 1.0) 84 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 85 | 86 | gl.glUseProgram(shader) 87 | gl.glBindVertexArray(vao) 88 | gl.glDrawElements(gl.GL_TRIANGLES, len(indices), gl.GL_UNSIGNED_INT, c_void_p(0)) 89 | 90 | glfw.poll_events() 91 | glfw.swap_buffers(window) 92 | 93 | gl.glDeleteVertexArrays(1, id(vao)) 94 | gl.glDeleteBuffers(1, id(vbo)) 95 | gl.glDeleteBuffers(1, id(ebo)) 96 | glfw.terminate() 97 | 98 | 99 | def on_resize(window, w, h): 100 | gl.glViewport(0, 0, w, h) 101 | 102 | 103 | def process_input(window): 104 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 105 | glfw.set_window_should_close(window, True) 106 | 107 | 108 | if __name__ == '__main__': 109 | main() 110 | -------------------------------------------------------------------------------- /source/1.getting_started/2.3.hello_triangle_exercise1.py: -------------------------------------------------------------------------------- 1 | import glfw 2 | import OpenGL.GL as gl 3 | from OpenGL.GL import shaders 4 | from ctypes import c_float, sizeof, c_void_p 5 | 6 | vertex_shader = """ 7 | #version 330 core 8 | 9 | layout (location = 0) in vec3 aPos; 10 | 11 | void main() { 12 | gl_Position = vec4(aPos, 1.0); 13 | } 14 | """ 15 | 16 | fragment_shader = """ 17 | #version 330 core 18 | 19 | out vec4 FragColor; 20 | 21 | void main() { 22 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 23 | } 24 | """ 25 | 26 | 27 | def main(): 28 | glfw.init() 29 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 30 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 31 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 32 | 33 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 34 | if not window: 35 | print("Window Creation failed!") 36 | glfw.terminate() 37 | 38 | glfw.make_context_current(window) 39 | glfw.set_window_size_callback(window, on_resize) 40 | 41 | shader = shaders.compileProgram( 42 | shaders.compileShader(vertex_shader, gl.GL_VERTEX_SHADER), 43 | shaders.compileShader(fragment_shader, gl.GL_FRAGMENT_SHADER), 44 | ) 45 | 46 | vertices = [ 47 | # first triangle 48 | -0.9, -0.5, 0.0, # left 49 | -0.0, -0.5, 0.0, # right 50 | -0.45, 0.5, 0.0, # top 51 | 52 | # second triangle 53 | 0.0, -0.5, 0.0, # left 54 | 0.9, -0.5, 0.0, # right 55 | 0.45, 0.5, 0.0 # top 56 | ] 57 | vertices = (c_float * len(vertices))(*vertices) 58 | 59 | vao = gl.glGenVertexArrays(1) 60 | gl.glBindVertexArray(vao) 61 | 62 | vbo = gl.glGenBuffers(1) 63 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 64 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 65 | 66 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 67 | gl.glEnableVertexAttribArray(0) 68 | 69 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) 70 | gl.glBindVertexArray(0) 71 | 72 | while not glfw.window_should_close(window): 73 | process_input(window) 74 | 75 | gl.glClearColor(.2, .3, .3, 1.0) 76 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 77 | 78 | gl.glUseProgram(shader) 79 | gl.glBindVertexArray(vao) 80 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) 81 | 82 | glfw.poll_events() 83 | glfw.swap_buffers(window) 84 | 85 | gl.glDeleteVertexArrays(1, id(vao)) 86 | gl.glDeleteBuffers(1, id(vbo)) 87 | glfw.terminate() 88 | 89 | 90 | def on_resize(window, w, h): 91 | gl.glViewport(0, 0, w, h) 92 | 93 | 94 | def process_input(window): 95 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 96 | glfw.set_window_should_close(window, True) 97 | 98 | 99 | if __name__ == '__main__': 100 | main() 101 | -------------------------------------------------------------------------------- /source/1.getting_started/2.3.hello_triangle_exercise2.py: -------------------------------------------------------------------------------- 1 | import glfw 2 | import OpenGL.GL as gl 3 | from OpenGL.GL import shaders 4 | from ctypes import c_float, sizeof, c_void_p 5 | 6 | vertex_shader = """ 7 | #version 330 core 8 | 9 | layout (location = 0) in vec3 aPos; 10 | 11 | void main() { 12 | gl_Position = vec4(aPos, 1.0); 13 | } 14 | """ 15 | 16 | fragment_shader = """ 17 | #version 330 core 18 | 19 | out vec4 FragColor; 20 | 21 | void main() { 22 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 23 | } 24 | """ 25 | 26 | 27 | def main(): 28 | glfw.init() 29 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 30 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 31 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 32 | 33 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 34 | if not window: 35 | print("Window Creation failed!") 36 | glfw.terminate() 37 | 38 | glfw.make_context_current(window) 39 | glfw.set_window_size_callback(window, on_resize) 40 | 41 | shader = shaders.compileProgram( 42 | shaders.compileShader(vertex_shader, gl.GL_VERTEX_SHADER), 43 | shaders.compileShader(fragment_shader, gl.GL_FRAGMENT_SHADER), 44 | ) 45 | 46 | vertices_tria_a = [ 47 | # first triangle 48 | -0.9, -0.5, 0.0, # left 49 | -0.0, -0.5, 0.0, # right 50 | -0.45, 0.5, 0.0, # top 51 | ] 52 | vertices_tria_a = (c_float * len(vertices_tria_a))(*vertices_tria_a) 53 | 54 | vertices_tria_b = [ 55 | # second triangle 56 | 0.0, -0.5, 0.0, # left 57 | 0.9, -0.5, 0.0, # right 58 | 0.45, 0.5, 0.0 # top 59 | ] 60 | vertices_tria_b = (c_float * len(vertices_tria_b))(*vertices_tria_b) 61 | 62 | vaos = gl.glGenVertexArrays(2) 63 | vbos = gl.glGenBuffers(2) 64 | 65 | gl.glBindVertexArray(vaos[0]) 66 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbos[0]) 67 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices_tria_a), vertices_tria_a, gl.GL_STATIC_DRAW) 68 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 69 | gl.glEnableVertexAttribArray(0) 70 | 71 | gl.glBindVertexArray(vaos[1]) 72 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbos[1]) 73 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices_tria_b), vertices_tria_b, gl.GL_STATIC_DRAW) 74 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 75 | gl.glEnableVertexAttribArray(0) 76 | 77 | while not glfw.window_should_close(window): 78 | process_input(window) 79 | 80 | gl.glClearColor(.2, .3, .3, 1.0) 81 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 82 | 83 | gl.glUseProgram(shader) 84 | gl.glBindVertexArray(vaos[0]) 85 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 86 | 87 | gl.glBindVertexArray(vaos[1]) 88 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 89 | 90 | glfw.poll_events() 91 | glfw.swap_buffers(window) 92 | 93 | gl.glDeleteVertexArrays(2, id(vaos)) 94 | gl.glDeleteBuffers(2, id(vbos)) 95 | glfw.terminate() 96 | 97 | 98 | def on_resize(window, w, h): 99 | gl.glViewport(0, 0, w, h) 100 | 101 | 102 | def process_input(window): 103 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 104 | glfw.set_window_should_close(window, True) 105 | 106 | 107 | if __name__ == '__main__': 108 | main() 109 | -------------------------------------------------------------------------------- /source/1.getting_started/2.3.hello_triangle_exercise3.py: -------------------------------------------------------------------------------- 1 | import glfw 2 | import OpenGL.GL as gl 3 | from OpenGL.GL import shaders 4 | from ctypes import c_float, sizeof, c_void_p 5 | 6 | vertex_shader = """ 7 | #version 330 core 8 | 9 | layout (location = 0) in vec3 aPos; 10 | 11 | void main() { 12 | gl_Position = vec4(aPos, 1.0); 13 | } 14 | """ 15 | 16 | fragment_shader_orange = """ 17 | #version 330 core 18 | 19 | out vec4 FragColor; 20 | 21 | void main() { 22 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 23 | } 24 | """ 25 | 26 | fragment_shader_yellow = """ 27 | #version 330 core 28 | 29 | out vec4 FragColor; 30 | 31 | void main() { 32 | FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f); 33 | } 34 | """ 35 | 36 | 37 | def main(): 38 | glfw.init() 39 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 40 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 41 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 42 | 43 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 44 | if not window: 45 | print("Window Creation failed!") 46 | glfw.terminate() 47 | 48 | glfw.make_context_current(window) 49 | glfw.set_window_size_callback(window, on_resize) 50 | 51 | shader_orange = shaders.compileProgram( 52 | shaders.compileShader(vertex_shader, gl.GL_VERTEX_SHADER), 53 | shaders.compileShader(fragment_shader_orange, gl.GL_FRAGMENT_SHADER), 54 | ) 55 | 56 | shader_yellow = shaders.compileProgram( 57 | shaders.compileShader(vertex_shader, gl.GL_VERTEX_SHADER), 58 | shaders.compileShader(fragment_shader_yellow, gl.GL_FRAGMENT_SHADER), 59 | ) 60 | 61 | vertices_tria_a = [ 62 | # first triangle 63 | -0.9, -0.5, 0.0, # left 64 | -0.0, -0.5, 0.0, # right 65 | -0.45, 0.5, 0.0, # top 66 | ] 67 | vertices_tria_a = (c_float * len(vertices_tria_a))(*vertices_tria_a) 68 | 69 | vertices_tria_b = [ 70 | # second triangle 71 | 0.0, -0.5, 0.0, # left 72 | 0.9, -0.5, 0.0, # right 73 | 0.45, 0.5, 0.0 # top 74 | ] 75 | vertices_tria_b = (c_float * len(vertices_tria_b))(*vertices_tria_b) 76 | 77 | vaos = gl.glGenVertexArrays(2) 78 | vbos = gl.glGenBuffers(2) 79 | 80 | gl.glBindVertexArray(vaos[0]) 81 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbos[0]) 82 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices_tria_a), vertices_tria_a, gl.GL_STATIC_DRAW) 83 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 84 | gl.glEnableVertexAttribArray(0) 85 | 86 | gl.glBindVertexArray(vaos[1]) 87 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbos[1]) 88 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices_tria_b), vertices_tria_b, gl.GL_STATIC_DRAW) 89 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 90 | gl.glEnableVertexAttribArray(0) 91 | 92 | while not glfw.window_should_close(window): 93 | process_input(window) 94 | 95 | gl.glClearColor(.2, .3, .3, 1.0) 96 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 97 | 98 | gl.glUseProgram(shader_orange) 99 | gl.glBindVertexArray(vaos[0]) 100 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 101 | 102 | gl.glUseProgram(shader_yellow) 103 | gl.glBindVertexArray(vaos[1]) 104 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 105 | 106 | glfw.poll_events() 107 | glfw.swap_buffers(window) 108 | 109 | gl.glDeleteVertexArrays(2, id(vaos)) 110 | gl.glDeleteBuffers(2, id(vbos)) 111 | glfw.terminate() 112 | 113 | 114 | def on_resize(window, w, h): 115 | gl.glViewport(0, 0, w, h) 116 | 117 | 118 | def process_input(window): 119 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 120 | glfw.set_window_should_close(window, True) 121 | 122 | 123 | if __name__ == '__main__': 124 | main() 125 | -------------------------------------------------------------------------------- /source/1.getting_started/3.1.shaders_uniform.py: -------------------------------------------------------------------------------- 1 | import math 2 | import glfw 3 | import OpenGL.GL as gl 4 | from OpenGL.GL import shaders 5 | from ctypes import c_float, sizeof, c_void_p 6 | 7 | 8 | vertex_shader = """ 9 | #version 330 core 10 | 11 | layout (location = 0) in vec3 aPos; 12 | 13 | void main() { 14 | gl_Position = vec4(aPos, 1.0); 15 | } 16 | """ 17 | 18 | fragment_shader = """ 19 | #version 330 core 20 | 21 | out vec4 FragColor; 22 | uniform vec4 ourColor; 23 | 24 | void main() { 25 | FragColor = ourColor; 26 | } 27 | """ 28 | 29 | 30 | def main(): 31 | glfw.init() 32 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 33 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 34 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 35 | 36 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 37 | if not window: 38 | print("Window Creation failed!") 39 | glfw.terminate() 40 | 41 | glfw.make_context_current(window) 42 | glfw.set_window_size_callback(window, on_resize) 43 | 44 | shader = shaders.compileProgram( 45 | shaders.compileShader(vertex_shader, gl.GL_VERTEX_SHADER), 46 | shaders.compileShader(fragment_shader, gl.GL_FRAGMENT_SHADER), 47 | ) 48 | 49 | vertices = [ 50 | -0.5, -0.5, 0.0, 51 | 0.5, -0.5, 0.0, 52 | 0.0, 0.5, 0.0, 53 | ] 54 | vertices = (c_float * len(vertices))(*vertices) 55 | 56 | vao = gl.glGenVertexArrays(1) 57 | gl.glBindVertexArray(vao) 58 | 59 | vbo = gl.glGenBuffers(1) 60 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 61 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 62 | 63 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 64 | gl.glEnableVertexAttribArray(0) 65 | 66 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) 67 | gl.glBindVertexArray(0) 68 | 69 | while not glfw.window_should_close(window): 70 | process_input(window) 71 | 72 | gl.glClearColor(.2, .3, .3, 1.0) 73 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 74 | 75 | gl.glUseProgram(shader) 76 | 77 | time = glfw.get_time() 78 | green_val = math.sin(time) / 2.0 + 0.5 79 | ourColor_location = gl.glGetUniformLocation(shader, "ourColor") 80 | gl.glUniform4f(ourColor_location, 0.0, green_val, 0.0, 1.0) 81 | 82 | gl.glBindVertexArray(vao) 83 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 84 | 85 | glfw.poll_events() 86 | glfw.swap_buffers(window) 87 | 88 | gl.glDeleteVertexArrays(1, id(vao)) 89 | gl.glDeleteBuffers(1, id(vbo)) 90 | glfw.terminate() 91 | 92 | 93 | def on_resize(window, w, h): 94 | gl.glViewport(0, 0, w, h) 95 | 96 | 97 | def process_input(window): 98 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 99 | glfw.set_window_should_close(window, True) 100 | 101 | 102 | if __name__ == '__main__': 103 | main() 104 | -------------------------------------------------------------------------------- /source/1.getting_started/3.2.shaders_interpolation.py: -------------------------------------------------------------------------------- 1 | import glfw 2 | import OpenGL.GL as gl 3 | from OpenGL.GL import shaders 4 | from ctypes import c_float, sizeof, c_void_p 5 | 6 | 7 | vertex_shader = """ 8 | #version 330 core 9 | 10 | layout (location = 0) in vec3 aPos; 11 | layout (location = 1) in vec3 aColor; 12 | 13 | out vec3 ourColor; 14 | 15 | void main() { 16 | gl_Position = vec4(aPos, 1.0); 17 | ourColor = aColor; 18 | } 19 | """ 20 | 21 | fragment_shader = """ 22 | #version 330 core 23 | 24 | in vec3 ourColor; 25 | out vec4 FragColor; 26 | 27 | void main() { 28 | FragColor = vec4(ourColor, 1.0f); 29 | } 30 | """ 31 | 32 | 33 | def main(): 34 | glfw.init() 35 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 36 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 37 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 38 | 39 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 40 | if not window: 41 | print("Window Creation failed!") 42 | glfw.terminate() 43 | 44 | glfw.make_context_current(window) 45 | glfw.set_window_size_callback(window, on_resize) 46 | 47 | shader = shaders.compileProgram( 48 | shaders.compileShader(vertex_shader, gl.GL_VERTEX_SHADER), 49 | shaders.compileShader(fragment_shader, gl.GL_FRAGMENT_SHADER), 50 | ) 51 | 52 | data = [ 53 | -0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 54 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 55 | 0.0, 0.5, 0.0, 0.0, 0.0, 1.0, 56 | ] 57 | data = (c_float * len(data))(*data) 58 | 59 | vao = gl.glGenVertexArrays(1) 60 | gl.glBindVertexArray(vao) 61 | 62 | vbo = gl.glGenBuffers(1) 63 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 64 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_STATIC_DRAW) 65 | 66 | # -- vertices 67 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(0)) 68 | gl.glEnableVertexAttribArray(0) 69 | 70 | # -- color 71 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 72 | gl.glEnableVertexAttribArray(1) 73 | 74 | while not glfw.window_should_close(window): 75 | process_input(window) 76 | 77 | gl.glClearColor(.2, .3, .3, 1.0) 78 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 79 | 80 | gl.glUseProgram(shader) 81 | gl.glBindVertexArray(vao) 82 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 83 | 84 | glfw.poll_events() 85 | glfw.swap_buffers(window) 86 | 87 | gl.glDeleteVertexArrays(1, id(vao)) 88 | gl.glDeleteBuffers(1, id(vbo)) 89 | glfw.terminate() 90 | 91 | 92 | def on_resize(window, w, h): 93 | gl.glViewport(0, 0, w, h) 94 | 95 | 96 | def process_input(window): 97 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 98 | glfw.set_window_should_close(window, True) 99 | 100 | 101 | if __name__ == '__main__': 102 | main() 103 | -------------------------------------------------------------------------------- /source/1.getting_started/3.3.shaders_class.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from pathlib import Path 5 | from ctypes import c_float, sizeof, c_void_p 6 | 7 | CURDIR = Path(__file__).parent.absolute() 8 | sys.path.append(str(CURDIR.parent)) 9 | 10 | from shader import Shader 11 | 12 | 13 | def main(): 14 | glfw.init() 15 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 16 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 17 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 18 | 19 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 20 | if not window: 21 | print("Window Creation failed!") 22 | glfw.terminate() 23 | 24 | glfw.make_context_current(window) 25 | glfw.set_window_size_callback(window, on_resize) 26 | 27 | shader = Shader(CURDIR / 'shaders/3.3.shader.vs', CURDIR / 'shaders/3.3.shader.fs') 28 | 29 | data = [ 30 | -0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 31 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 32 | 0.0, 0.5, 0.0, 0.0, 0.0, 1.0, 33 | ] 34 | data = (c_float * len(data))(*data) 35 | 36 | vao = gl.glGenVertexArrays(1) 37 | gl.glBindVertexArray(vao) 38 | 39 | vbo = gl.glGenBuffers(1) 40 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 41 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_STATIC_DRAW) 42 | 43 | # -- vertices 44 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(0)) 45 | gl.glEnableVertexAttribArray(0) 46 | 47 | # -- color 48 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 49 | gl.glEnableVertexAttribArray(1) 50 | 51 | while not glfw.window_should_close(window): 52 | process_input(window) 53 | 54 | gl.glClearColor(.2, .3, .3, 1.0) 55 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 56 | 57 | shader.use() 58 | gl.glBindVertexArray(vao) 59 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 60 | 61 | glfw.poll_events() 62 | glfw.swap_buffers(window) 63 | 64 | gl.glDeleteVertexArrays(1, id(vao)) 65 | gl.glDeleteBuffers(1, id(vbo)) 66 | glfw.terminate() 67 | 68 | 69 | def on_resize(window, w, h): 70 | gl.glViewport(0, 0, w, h) 71 | 72 | 73 | def process_input(window): 74 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 75 | glfw.set_window_should_close(window, True) 76 | 77 | 78 | if __name__ == '__main__': 79 | main() 80 | -------------------------------------------------------------------------------- /source/1.getting_started/3.4.shaders_exercise1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from pathlib import Path 5 | from ctypes import c_float, sizeof, c_void_p 6 | 7 | CURDIR = Path(__file__).parent.absolute() 8 | sys.path.append(str(CURDIR.parent)) 9 | 10 | from shader import Shader 11 | 12 | 13 | def main(): 14 | glfw.init() 15 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 16 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 17 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 18 | 19 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 20 | if not window: 21 | print("Window Creation failed!") 22 | glfw.terminate() 23 | 24 | glfw.make_context_current(window) 25 | glfw.set_window_size_callback(window, on_resize) 26 | 27 | shader = Shader(CURDIR / 'shaders/3.4.shader.vs', CURDIR / 'shaders/3.4.shader.fs') 28 | 29 | data = [ 30 | -0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 31 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 32 | 0.0, 0.5, 0.0, 0.0, 0.0, 1.0, 33 | ] 34 | data = (c_float * len(data))(*data) 35 | 36 | vao = gl.glGenVertexArrays(1) 37 | gl.glBindVertexArray(vao) 38 | 39 | vbo = gl.glGenBuffers(1) 40 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 41 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_STATIC_DRAW) 42 | 43 | # -- vertices 44 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(0)) 45 | gl.glEnableVertexAttribArray(0) 46 | 47 | # -- color 48 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 49 | gl.glEnableVertexAttribArray(1) 50 | 51 | while not glfw.window_should_close(window): 52 | process_input(window) 53 | 54 | gl.glClearColor(.2, .3, .3, 1.0) 55 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 56 | 57 | shader.use() 58 | gl.glBindVertexArray(vao) 59 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 60 | 61 | glfw.poll_events() 62 | glfw.swap_buffers(window) 63 | 64 | gl.glDeleteVertexArrays(1, id(vao)) 65 | gl.glDeleteBuffers(1, id(vbo)) 66 | glfw.terminate() 67 | 68 | 69 | def on_resize(window, w, h): 70 | gl.glViewport(0, 0, w, h) 71 | 72 | 73 | def process_input(window): 74 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 75 | glfw.set_window_should_close(window, True) 76 | 77 | 78 | if __name__ == '__main__': 79 | main() 80 | -------------------------------------------------------------------------------- /source/1.getting_started/3.5.shaders_exercise2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from pathlib import Path 5 | from ctypes import c_float, sizeof, c_void_p 6 | 7 | CURDIR = Path(__file__).parent.absolute() 8 | sys.path.append(str(CURDIR.parent)) 9 | 10 | from shader import Shader 11 | 12 | 13 | def main(): 14 | glfw.init() 15 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 16 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 17 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 18 | 19 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 20 | if not window: 21 | print("Window Creation failed!") 22 | glfw.terminate() 23 | 24 | glfw.make_context_current(window) 25 | glfw.set_window_size_callback(window, on_resize) 26 | 27 | shader = Shader(CURDIR / 'shaders/3.5.shader.vs', CURDIR / 'shaders/3.5.shader.fs') 28 | 29 | data = [ 30 | -0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 31 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 32 | 0.0, 0.5, 0.0, 0.0, 0.0, 1.0, 33 | ] 34 | data = (c_float * len(data))(*data) 35 | 36 | vao = gl.glGenVertexArrays(1) 37 | gl.glBindVertexArray(vao) 38 | 39 | vbo = gl.glGenBuffers(1) 40 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 41 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_STATIC_DRAW) 42 | 43 | # -- vertices 44 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(0)) 45 | gl.glEnableVertexAttribArray(0) 46 | 47 | # -- color 48 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 6 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 49 | gl.glEnableVertexAttribArray(1) 50 | 51 | while not glfw.window_should_close(window): 52 | process_input(window) 53 | 54 | gl.glClearColor(.2, .3, .3, 1.0) 55 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 56 | 57 | shader.use() 58 | shader.set_float("offset", .5) 59 | gl.glBindVertexArray(vao) 60 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 61 | 62 | glfw.poll_events() 63 | glfw.swap_buffers(window) 64 | 65 | gl.glDeleteVertexArrays(1, id(vao)) 66 | gl.glDeleteBuffers(1, id(vbo)) 67 | glfw.terminate() 68 | 69 | 70 | def on_resize(window, w, h): 71 | gl.glViewport(0, 0, w, h) 72 | 73 | 74 | def process_input(window): 75 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 76 | glfw.set_window_should_close(window, True) 77 | 78 | 79 | if __name__ == '__main__': 80 | main() 81 | -------------------------------------------------------------------------------- /source/1.getting_started/3.6.shaders_exercise3.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from pathlib import Path 5 | from ctypes import c_float, sizeof, c_void_p 6 | 7 | CURDIR = Path(__file__).parent.absolute() 8 | sys.path.append(str(CURDIR.parent)) 9 | 10 | from shader import Shader 11 | 12 | 13 | """ 14 | Why is the bottom left corner black? 15 | 16 | Because colors are interpreted as floats in the range 0.0 - 1.0, 17 | the bottom left coordinate (-0.5, -0.5, 0.0) gets interpreted as 18 | the color (0.0, 0.0, 0.0) which is black. 19 | """ 20 | 21 | 22 | def main(): 23 | glfw.init() 24 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 25 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 26 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 27 | 28 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 29 | if not window: 30 | print("Window Creation failed!") 31 | glfw.terminate() 32 | 33 | glfw.make_context_current(window) 34 | glfw.set_window_size_callback(window, on_resize) 35 | 36 | shader = Shader(CURDIR / 'shaders/3.6.shader.vs', CURDIR / 'shaders/3.6.shader.fs') 37 | 38 | data = [ 39 | -0.5, -0.5, 0.0, 40 | 0.5, -0.5, 0.0, 41 | 0.0, 0.5, 0.0, 42 | ] 43 | data = (c_float * len(data))(*data) 44 | 45 | vao = gl.glGenVertexArrays(1) 46 | gl.glBindVertexArray(vao) 47 | 48 | vbo = gl.glGenBuffers(1) 49 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 50 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_STATIC_DRAW) 51 | 52 | # -- vertices 53 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 54 | gl.glEnableVertexAttribArray(0) 55 | 56 | while not glfw.window_should_close(window): 57 | process_input(window) 58 | 59 | gl.glClearColor(.2, .3, .3, 1.0) 60 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 61 | 62 | shader.use() 63 | gl.glBindVertexArray(vao) 64 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) 65 | 66 | glfw.poll_events() 67 | glfw.swap_buffers(window) 68 | 69 | gl.glDeleteVertexArrays(1, id(vao)) 70 | gl.glDeleteBuffers(1, id(vbo)) 71 | glfw.terminate() 72 | 73 | 74 | def on_resize(window, w, h): 75 | gl.glViewport(0, 0, w, h) 76 | 77 | 78 | def process_input(window): 79 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 80 | glfw.set_window_should_close(window, True) 81 | 82 | 83 | if __name__ == '__main__': 84 | main() 85 | -------------------------------------------------------------------------------- /source/1.getting_started/4.1.textures.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from PIL import Image 5 | from pathlib import Path 6 | from ctypes import c_uint, c_float, sizeof, c_void_p 7 | 8 | CURDIR = Path(__file__).parent.absolute() 9 | RESDIR = CURDIR.parent.parent.joinpath("resources") 10 | sys.path.append(str(CURDIR.parent)) 11 | from shader import Shader 12 | 13 | 14 | def Tex(fn): 15 | return RESDIR.joinpath("textures", fn) 16 | 17 | 18 | def main(): 19 | glfw.init() 20 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 21 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 22 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 23 | 24 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 25 | if not window: 26 | print("Window Creation failed!") 27 | glfw.terminate() 28 | 29 | glfw.make_context_current(window) 30 | glfw.set_window_size_callback(window, on_resize) 31 | 32 | shader = Shader(CURDIR / 'shaders/4.1.texture.vs', CURDIR / 'shaders/4.1.texture.fs') 33 | shader_mix = Shader(CURDIR / 'shaders/4.1.texture.vs', CURDIR / 'shaders/4.1.texture_mix.fs') 34 | 35 | vertices = [ 36 | # positions colors tex_coords 37 | 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, # top right 38 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, # bottom right 39 | -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, # bottom left 40 | -0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, # top left 41 | ] 42 | vertices = (c_float * len(vertices))(*vertices) 43 | 44 | indices = [ 45 | 0, 1, 3, 46 | 1, 2, 3 47 | ] 48 | indices = (c_uint * len(indices))(*indices) 49 | 50 | vao = gl.glGenVertexArrays(1) 51 | gl.glBindVertexArray(vao) 52 | 53 | vbo = gl.glGenBuffers(1) 54 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 55 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 56 | 57 | ebo = gl.glGenBuffers(1) 58 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 59 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 60 | 61 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(0)) 62 | gl.glEnableVertexAttribArray(0) 63 | 64 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 65 | gl.glEnableVertexAttribArray(1) 66 | 67 | gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(6 * sizeof(c_float))) 68 | gl.glEnableVertexAttribArray(2) 69 | 70 | # -- load texture 71 | texture = gl.glGenTextures(1) 72 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture) 73 | # -- texture wrapping 74 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 75 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 76 | # -- texture filterting 77 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR_MIPMAP_LINEAR) 78 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 79 | 80 | img = Image.open(Tex('container.jpg')) 81 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 82 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 83 | 84 | while not glfw.window_should_close(window): 85 | process_input(window) 86 | 87 | gl.glClearColor(.2, .3, .3, 1.0) 88 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 89 | 90 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture) 91 | shader.use() 92 | # -- uncomment to see mixture of vertex color and texture color 93 | # shader_mix.use() 94 | gl.glBindVertexArray(vao) 95 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 96 | 97 | glfw.poll_events() 98 | glfw.swap_buffers(window) 99 | 100 | gl.glDeleteVertexArrays(1, id(vao)) 101 | gl.glDeleteBuffers(1, id(vbo)) 102 | gl.glDeleteBuffers(1, id(ebo)) 103 | glfw.terminate() 104 | 105 | 106 | def on_resize(window, w, h): 107 | gl.glViewport(0, 0, w, h) 108 | 109 | 110 | def process_input(window): 111 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 112 | glfw.set_window_should_close(window, True) 113 | 114 | 115 | if __name__ == '__main__': 116 | main() 117 | -------------------------------------------------------------------------------- /source/1.getting_started/4.2.textures_combined.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from PIL import Image 5 | from pathlib import Path 6 | from ctypes import c_uint, c_float, sizeof, c_void_p 7 | 8 | CURDIR = Path(__file__).parent.absolute() 9 | RESDIR = CURDIR.parent.parent.joinpath("resources") 10 | sys.path.append(str(CURDIR.parent)) 11 | from shader import Shader 12 | 13 | 14 | def Tex(fn): 15 | return RESDIR.joinpath("textures", fn) 16 | 17 | 18 | def main(): 19 | glfw.init() 20 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 21 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 22 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 23 | 24 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 25 | if not window: 26 | print("Window Creation failed!") 27 | glfw.terminate() 28 | 29 | glfw.make_context_current(window) 30 | glfw.set_window_size_callback(window, on_resize) 31 | 32 | shader = Shader(CURDIR / 'shaders/4.2.texture.vs', CURDIR / 'shaders/4.2.texture.fs') 33 | 34 | vertices = [ 35 | # positions colors tex_coords 36 | 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, # top right 37 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, # bottom right 38 | -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, # bottom left 39 | -0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, # top left 40 | ] 41 | vertices = (c_float * len(vertices))(*vertices) 42 | 43 | indices = [ 44 | 0, 1, 3, 45 | 1, 2, 3 46 | ] 47 | indices = (c_uint * len(indices))(*indices) 48 | 49 | vao = gl.glGenVertexArrays(1) 50 | gl.glBindVertexArray(vao) 51 | 52 | vbo = gl.glGenBuffers(1) 53 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 54 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 55 | 56 | ebo = gl.glGenBuffers(1) 57 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 58 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 59 | 60 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(0)) 61 | gl.glEnableVertexAttribArray(0) 62 | 63 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 64 | gl.glEnableVertexAttribArray(1) 65 | 66 | gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(6 * sizeof(c_float))) 67 | gl.glEnableVertexAttribArray(2) 68 | 69 | # -- load texture 1 70 | texture1 = gl.glGenTextures(1) 71 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 72 | # -- texture wrapping 73 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 74 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 75 | # -- texture filterting 76 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 77 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 78 | 79 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 80 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 81 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 82 | 83 | # -- load texture 2 84 | texture2 = gl.glGenTextures(1) 85 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 86 | # -- texture wrapping 87 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 88 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 89 | # -- texture filterting 90 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 91 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 92 | 93 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 94 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 95 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 96 | 97 | shader.use() 98 | shader.set_int("texture1", 0) 99 | shader.set_int("texture2", 1) 100 | 101 | while not glfw.window_should_close(window): 102 | process_input(window) 103 | 104 | gl.glClearColor(.2, .3, .3, 1.0) 105 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 106 | 107 | gl.glActiveTexture(gl.GL_TEXTURE0) 108 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 109 | gl.glActiveTexture(gl.GL_TEXTURE1) 110 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 111 | 112 | shader.use() 113 | gl.glBindVertexArray(vao) 114 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 115 | 116 | glfw.poll_events() 117 | glfw.swap_buffers(window) 118 | 119 | gl.glDeleteVertexArrays(1, id(vao)) 120 | gl.glDeleteBuffers(1, id(vbo)) 121 | gl.glDeleteBuffers(1, id(ebo)) 122 | glfw.terminate() 123 | 124 | 125 | def on_resize(window, w, h): 126 | gl.glViewport(0, 0, w, h) 127 | 128 | 129 | def process_input(window): 130 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 131 | glfw.set_window_should_close(window, True) 132 | 133 | 134 | if __name__ == '__main__': 135 | main() 136 | -------------------------------------------------------------------------------- /source/1.getting_started/4.3.textures_exercise1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from PIL import Image 5 | from pathlib import Path 6 | from ctypes import c_uint, c_float, sizeof, c_void_p 7 | 8 | CURDIR = Path(__file__).parent.absolute() 9 | RESDIR = CURDIR.parent.parent.joinpath("resources") 10 | sys.path.append(str(CURDIR.parent)) 11 | from shader import Shader 12 | 13 | 14 | def Tex(fn): 15 | return RESDIR.joinpath("textures", fn) 16 | 17 | 18 | def main(): 19 | glfw.init() 20 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 21 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 22 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 23 | 24 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 25 | if not window: 26 | print("Window Creation failed!") 27 | glfw.terminate() 28 | 29 | glfw.make_context_current(window) 30 | glfw.set_window_size_callback(window, on_resize) 31 | 32 | shader = Shader(CURDIR / 'shaders/4.3.texture_exercise1.vs', CURDIR / 'shaders/4.3.texture_exercise1.fs') 33 | 34 | vertices = [ 35 | # positions colors tex_coords 36 | 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, # top right 37 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, # bottom right 38 | -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, # bottom left 39 | -0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, # top left 40 | ] 41 | vertices = (c_float * len(vertices))(*vertices) 42 | 43 | indices = [ 44 | 0, 1, 3, 45 | 1, 2, 3 46 | ] 47 | indices = (c_uint * len(indices))(*indices) 48 | 49 | vao = gl.glGenVertexArrays(1) 50 | gl.glBindVertexArray(vao) 51 | 52 | vbo = gl.glGenBuffers(1) 53 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 54 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 55 | 56 | ebo = gl.glGenBuffers(1) 57 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 58 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 59 | 60 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(0)) 61 | gl.glEnableVertexAttribArray(0) 62 | 63 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 64 | gl.glEnableVertexAttribArray(1) 65 | 66 | gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(6 * sizeof(c_float))) 67 | gl.glEnableVertexAttribArray(2) 68 | 69 | # -- load texture 1 70 | texture1 = gl.glGenTextures(1) 71 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 72 | # -- texture wrapping 73 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 74 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 75 | # -- texture filterting 76 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 77 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 78 | 79 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 80 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 81 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 82 | 83 | # -- load texture 2 84 | texture2 = gl.glGenTextures(1) 85 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 86 | # -- texture wrapping 87 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 88 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 89 | # -- texture filterting 90 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 91 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 92 | 93 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 94 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 95 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 96 | 97 | shader.use() 98 | shader.set_int("texture1", 0) 99 | shader.set_int("texture2", 1) 100 | 101 | while not glfw.window_should_close(window): 102 | process_input(window) 103 | 104 | gl.glClearColor(.2, .3, .3, 1.0) 105 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 106 | 107 | gl.glActiveTexture(gl.GL_TEXTURE0) 108 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 109 | gl.glActiveTexture(gl.GL_TEXTURE1) 110 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 111 | 112 | shader.use() 113 | gl.glBindVertexArray(vao) 114 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 115 | 116 | glfw.poll_events() 117 | glfw.swap_buffers(window) 118 | 119 | gl.glDeleteVertexArrays(1, id(vao)) 120 | gl.glDeleteBuffers(1, id(vbo)) 121 | gl.glDeleteBuffers(1, id(ebo)) 122 | glfw.terminate() 123 | 124 | 125 | def on_resize(window, w, h): 126 | gl.glViewport(0, 0, w, h) 127 | 128 | 129 | def process_input(window): 130 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 131 | glfw.set_window_should_close(window, True) 132 | 133 | 134 | if __name__ == '__main__': 135 | main() 136 | -------------------------------------------------------------------------------- /source/1.getting_started/4.4.textures_exercise2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from PIL import Image 5 | from pathlib import Path 6 | from ctypes import c_uint, c_float, sizeof, c_void_p 7 | 8 | CURDIR = Path(__file__).parent.absolute() 9 | RESDIR = CURDIR.parent.parent.joinpath("resources") 10 | sys.path.append(str(CURDIR.parent)) 11 | from shader import Shader 12 | 13 | 14 | def Tex(fn): 15 | return RESDIR.joinpath("textures", fn) 16 | 17 | 18 | def main(): 19 | glfw.init() 20 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 21 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 22 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 23 | 24 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 25 | if not window: 26 | print("Window Creation failed!") 27 | glfw.terminate() 28 | 29 | glfw.make_context_current(window) 30 | glfw.set_window_size_callback(window, on_resize) 31 | 32 | shader = Shader(CURDIR / 'shaders/4.2.texture.vs', CURDIR / 'shaders/4.2.texture.fs') 33 | 34 | vertices = [ 35 | # positions colors tex_coords 36 | 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 2.0, 2.0, # top right 37 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 2.0, 0.0, # bottom right 38 | -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, # bottom left 39 | -0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 2.0, # top left 40 | ] 41 | vertices = (c_float * len(vertices))(*vertices) 42 | 43 | indices = [ 44 | 0, 1, 3, 45 | 1, 2, 3 46 | ] 47 | indices = (c_uint * len(indices))(*indices) 48 | 49 | vao = gl.glGenVertexArrays(1) 50 | gl.glBindVertexArray(vao) 51 | 52 | vbo = gl.glGenBuffers(1) 53 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 54 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 55 | 56 | ebo = gl.glGenBuffers(1) 57 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 58 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 59 | 60 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(0)) 61 | gl.glEnableVertexAttribArray(0) 62 | 63 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 64 | gl.glEnableVertexAttribArray(1) 65 | 66 | gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(6 * sizeof(c_float))) 67 | gl.glEnableVertexAttribArray(2) 68 | 69 | # -- load texture 1 70 | texture1 = gl.glGenTextures(1) 71 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 72 | # -- texture wrapping 73 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE) 74 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE) 75 | # -- texture filterting 76 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 77 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 78 | 79 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 80 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 81 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 82 | 83 | # -- load texture 2 84 | texture2 = gl.glGenTextures(1) 85 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 86 | # -- texture wrapping 87 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 88 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 89 | # -- texture filterting 90 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 91 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 92 | 93 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 94 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 95 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 96 | 97 | shader.use() 98 | shader.set_int("texture1", 0) 99 | shader.set_int("texture2", 1) 100 | 101 | while not glfw.window_should_close(window): 102 | process_input(window) 103 | 104 | gl.glClearColor(.2, .3, .3, 1.0) 105 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 106 | 107 | gl.glActiveTexture(gl.GL_TEXTURE0) 108 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 109 | gl.glActiveTexture(gl.GL_TEXTURE1) 110 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 111 | 112 | shader.use() 113 | gl.glBindVertexArray(vao) 114 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 115 | 116 | glfw.poll_events() 117 | glfw.swap_buffers(window) 118 | 119 | gl.glDeleteVertexArrays(1, id(vao)) 120 | gl.glDeleteBuffers(1, id(vbo)) 121 | gl.glDeleteBuffers(1, id(ebo)) 122 | glfw.terminate() 123 | 124 | 125 | def on_resize(window, w, h): 126 | gl.glViewport(0, 0, w, h) 127 | 128 | 129 | def process_input(window): 130 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 131 | glfw.set_window_should_close(window, True) 132 | 133 | 134 | if __name__ == '__main__': 135 | main() 136 | -------------------------------------------------------------------------------- /source/1.getting_started/4.5.textures_exercise3.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from PIL import Image 5 | from pathlib import Path 6 | from ctypes import c_uint, c_float, sizeof, c_void_p 7 | 8 | CURDIR = Path(__file__).parent.absolute() 9 | RESDIR = CURDIR.parent.parent.joinpath("resources") 10 | sys.path.append(str(CURDIR.parent)) 11 | from shader import Shader 12 | 13 | 14 | def Tex(fn): 15 | return RESDIR.joinpath("textures", fn) 16 | 17 | 18 | def main(): 19 | glfw.init() 20 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 21 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 22 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 23 | 24 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 25 | if not window: 26 | print("Window Creation failed!") 27 | glfw.terminate() 28 | 29 | glfw.make_context_current(window) 30 | glfw.set_window_size_callback(window, on_resize) 31 | 32 | shader = Shader(CURDIR / 'shaders/4.2.texture.vs', CURDIR / 'shaders/4.2.texture.fs') 33 | 34 | vertices = [ 35 | # positions colors tex_coords 36 | 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 0.55, 0.55, # top right 37 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 0.55, 0.45, # bottom right 38 | -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.45, 0.45, # bottom left 39 | -0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.45, 0.55, # top left 40 | ] 41 | vertices = (c_float * len(vertices))(*vertices) 42 | 43 | indices = [ 44 | 0, 1, 3, 45 | 1, 2, 3 46 | ] 47 | indices = (c_uint * len(indices))(*indices) 48 | 49 | vao = gl.glGenVertexArrays(1) 50 | gl.glBindVertexArray(vao) 51 | 52 | vbo = gl.glGenBuffers(1) 53 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 54 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 55 | 56 | ebo = gl.glGenBuffers(1) 57 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 58 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 59 | 60 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(0)) 61 | gl.glEnableVertexAttribArray(0) 62 | 63 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 64 | gl.glEnableVertexAttribArray(1) 65 | 66 | gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(6 * sizeof(c_float))) 67 | gl.glEnableVertexAttribArray(2) 68 | 69 | # -- load texture 1 70 | texture1 = gl.glGenTextures(1) 71 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 72 | # -- texture wrapping 73 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE) 74 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE) 75 | # -- texture filterting 76 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) 77 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) 78 | 79 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 80 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 81 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 82 | 83 | # # -- load texture 2 84 | texture2 = gl.glGenTextures(1) 85 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 86 | # -- texture wrapping 87 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 88 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 89 | # -- texture filterting 90 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) 91 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) 92 | 93 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 94 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 95 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 96 | 97 | shader.use() 98 | shader.set_int("texture1", 0) 99 | shader.set_int("texture2", 1) 100 | 101 | while not glfw.window_should_close(window): 102 | process_input(window) 103 | 104 | gl.glClearColor(.2, .3, .3, 1.0) 105 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 106 | 107 | gl.glActiveTexture(gl.GL_TEXTURE0) 108 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 109 | gl.glActiveTexture(gl.GL_TEXTURE1) 110 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 111 | 112 | shader.use() 113 | gl.glBindVertexArray(vao) 114 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 115 | 116 | glfw.poll_events() 117 | glfw.swap_buffers(window) 118 | 119 | gl.glDeleteVertexArrays(1, id(vao)) 120 | gl.glDeleteBuffers(1, id(vbo)) 121 | gl.glDeleteBuffers(1, id(ebo)) 122 | glfw.terminate() 123 | 124 | 125 | def on_resize(window, w, h): 126 | gl.glViewport(0, 0, w, h) 127 | 128 | 129 | def process_input(window): 130 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 131 | glfw.set_window_should_close(window, True) 132 | 133 | 134 | if __name__ == '__main__': 135 | main() 136 | -------------------------------------------------------------------------------- /source/1.getting_started/4.6.textures_exercise4.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from PIL import Image 5 | from pathlib import Path 6 | from ctypes import c_uint, c_float, sizeof, c_void_p 7 | 8 | CURDIR = Path(__file__).parent.absolute() 9 | RESDIR = CURDIR.parent.parent.joinpath("resources") 10 | sys.path.append(str(CURDIR.parent)) 11 | from shader import Shader 12 | 13 | 14 | def Tex(fn): 15 | return RESDIR.joinpath("textures", fn) 16 | 17 | 18 | mix_value = 0.2 19 | 20 | 21 | def main(): 22 | global mix_value 23 | 24 | glfw.init() 25 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 26 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 27 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 28 | 29 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 30 | if not window: 31 | print("Window Creation failed!") 32 | glfw.terminate() 33 | 34 | glfw.make_context_current(window) 35 | glfw.set_window_size_callback(window, on_resize) 36 | 37 | shader = Shader(CURDIR / 'shaders/4.6.texture_exercise4.vs', CURDIR / 'shaders/4.6.texture_exercise4.fs') 38 | 39 | vertices = [ 40 | # positions colors tex_coords 41 | 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, # top right 42 | 0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, # bottom right 43 | -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, # bottom left 44 | -0.5, 0.5, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, # top left 45 | ] 46 | vertices = (c_float * len(vertices))(*vertices) 47 | 48 | indices = [ 49 | 0, 1, 3, 50 | 1, 2, 3 51 | ] 52 | indices = (c_uint * len(indices))(*indices) 53 | 54 | vao = gl.glGenVertexArrays(1) 55 | gl.glBindVertexArray(vao) 56 | 57 | vbo = gl.glGenBuffers(1) 58 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 59 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 60 | 61 | ebo = gl.glGenBuffers(1) 62 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 63 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 64 | 65 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(0)) 66 | gl.glEnableVertexAttribArray(0) 67 | 68 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 69 | gl.glEnableVertexAttribArray(1) 70 | 71 | gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 8 * sizeof(c_float), c_void_p(6 * sizeof(c_float))) 72 | gl.glEnableVertexAttribArray(2) 73 | 74 | # -- load texture 1 75 | texture1 = gl.glGenTextures(1) 76 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 77 | # -- texture wrapping 78 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 79 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 80 | # -- texture filterting 81 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 82 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 83 | 84 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 85 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 86 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 87 | 88 | # -- load texture 2 89 | texture2 = gl.glGenTextures(1) 90 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 91 | # -- texture wrapping 92 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 93 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 94 | # -- texture filterting 95 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 96 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 97 | 98 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 99 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 100 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 101 | 102 | shader.use() 103 | shader.set_int("texture1", 0) 104 | shader.set_int("texture2", 1) 105 | 106 | while not glfw.window_should_close(window): 107 | process_input(window) 108 | 109 | gl.glClearColor(.2, .3, .3, 1.0) 110 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 111 | 112 | gl.glActiveTexture(gl.GL_TEXTURE0) 113 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 114 | gl.glActiveTexture(gl.GL_TEXTURE1) 115 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 116 | 117 | shader.use() 118 | shader.set_float("mix_value", round(mix_value, 4)) 119 | gl.glBindVertexArray(vao) 120 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 121 | 122 | glfw.poll_events() 123 | glfw.swap_buffers(window) 124 | 125 | gl.glDeleteVertexArrays(1, id(vao)) 126 | gl.glDeleteBuffers(1, id(vbo)) 127 | gl.glDeleteBuffers(1, id(ebo)) 128 | glfw.terminate() 129 | 130 | 131 | def on_resize(window, w, h): 132 | gl.glViewport(0, 0, w, h) 133 | 134 | 135 | def process_input(window): 136 | global mix_value 137 | 138 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 139 | glfw.set_window_should_close(window, True) 140 | 141 | if glfw.get_key(window, glfw.KEY_UP) == glfw.PRESS: 142 | mix_value += 0.001 143 | if mix_value > 1.0: 144 | mix_value = 1.0 145 | 146 | if glfw.get_key(window, glfw.KEY_DOWN) == glfw.PRESS: 147 | mix_value -= 0.001 148 | if mix_value < 0.0: 149 | mix_value = 0.0 150 | 151 | 152 | if __name__ == '__main__': 153 | main() 154 | -------------------------------------------------------------------------------- /source/1.getting_started/5.1.transformations.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from PIL import Image 5 | from pathlib import Path 6 | from pyrr import Matrix44 7 | from ctypes import c_uint, c_float, sizeof, c_void_p 8 | 9 | CURDIR = Path(__file__).parent.absolute() 10 | RESDIR = CURDIR.parent.parent.joinpath("resources") 11 | sys.path.append(str(CURDIR.parent)) 12 | 13 | from shader import Shader 14 | 15 | 16 | def Tex(fn): 17 | return RESDIR.joinpath("textures", fn) 18 | 19 | 20 | def main(): 21 | glfw.init() 22 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 23 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 24 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 25 | 26 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 27 | if not window: 28 | print("Window Creation failed!") 29 | glfw.terminate() 30 | 31 | glfw.make_context_current(window) 32 | glfw.set_window_size_callback(window, on_resize) 33 | 34 | shader = Shader(CURDIR / 'shaders/5.1.transform.vs', CURDIR / 'shaders/5.1.transform.fs') 35 | 36 | vertices = [ 37 | # positions tex_coords 38 | 0.5, 0.5, 0.0, 1.0, 1.0, # top right 39 | 0.5, -0.5, 0.0, 1.0, 0.0, # bottom right 40 | -0.5, -0.5, 0.0, 0.0, 0.0, # bottom left 41 | -0.5, 0.5, 0.0, 0.0, 1.0, # top left 42 | ] 43 | vertices = (c_float * len(vertices))(*vertices) 44 | 45 | indices = [ 46 | 0, 1, 3, 47 | 1, 2, 3 48 | ] 49 | indices = (c_uint * len(indices))(*indices) 50 | 51 | vao = gl.glGenVertexArrays(1) 52 | gl.glBindVertexArray(vao) 53 | 54 | vbo = gl.glGenBuffers(1) 55 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 56 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 57 | 58 | ebo = gl.glGenBuffers(1) 59 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 60 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 61 | 62 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) 63 | gl.glEnableVertexAttribArray(0) 64 | 65 | gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 66 | gl.glEnableVertexAttribArray(1) 67 | 68 | # -- load texture 1 69 | texture1 = gl.glGenTextures(1) 70 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 71 | # -- texture wrapping 72 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 73 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 74 | # -- texture filterting 75 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 76 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 77 | 78 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 79 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 80 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 81 | 82 | # -- load texture 2 83 | texture2 = gl.glGenTextures(1) 84 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 85 | # -- texture wrapping 86 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 87 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 88 | # -- texture filterting 89 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 90 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 91 | 92 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 93 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 94 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 95 | 96 | shader.use() 97 | shader.set_int("texture1", 0) 98 | shader.set_int("texture2", 1) 99 | 100 | while not glfw.window_should_close(window): 101 | process_input(window) 102 | 103 | gl.glClearColor(.2, .3, .3, 1.0) 104 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 105 | 106 | gl.glActiveTexture(gl.GL_TEXTURE0) 107 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 108 | gl.glActiveTexture(gl.GL_TEXTURE1) 109 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 110 | 111 | translation = Matrix44.from_translation([0.5, -0.5, 0.0]) 112 | rotation = Matrix44.from_z_rotation(glfw.get_time()) 113 | transform = translation * rotation 114 | 115 | shader.use() 116 | shader.set_mat4('transform', transform) 117 | gl.glBindVertexArray(vao) 118 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 119 | 120 | glfw.poll_events() 121 | glfw.swap_buffers(window) 122 | 123 | gl.glDeleteVertexArrays(1, id(vao)) 124 | gl.glDeleteBuffers(1, id(vbo)) 125 | gl.glDeleteBuffers(1, id(ebo)) 126 | glfw.terminate() 127 | 128 | 129 | def on_resize(window, w, h): 130 | gl.glViewport(0, 0, w, h) 131 | 132 | 133 | def process_input(window): 134 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 135 | glfw.set_window_should_close(window, True) 136 | 137 | 138 | if __name__ == '__main__': 139 | main() 140 | -------------------------------------------------------------------------------- /source/1.getting_started/5.2.transformation_exercise2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import glfw 4 | import OpenGL.GL as gl 5 | from PIL import Image 6 | from pathlib import Path 7 | from pyrr import Matrix44 8 | from ctypes import c_uint, c_float, sizeof, c_void_p 9 | 10 | CURDIR = Path(__file__).parent.absolute() 11 | RESDIR = CURDIR.parent.parent.joinpath("resources") 12 | sys.path.append(str(CURDIR.parent)) 13 | from shader import Shader 14 | 15 | 16 | def Tex(fn): 17 | return RESDIR.joinpath("textures", fn) 18 | 19 | 20 | def main(): 21 | glfw.init() 22 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 23 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 24 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 25 | 26 | window = glfw.create_window(800, 600, "LearnOpenGL", None, None) 27 | if not window: 28 | print("Window Creation failed!") 29 | glfw.terminate() 30 | 31 | glfw.make_context_current(window) 32 | glfw.set_window_size_callback(window, on_resize) 33 | 34 | shader = Shader(CURDIR / 'shaders/5.1.transform.vs', CURDIR / 'shaders/5.1.transform.fs') 35 | 36 | vertices = [ 37 | # positions tex_coords 38 | 0.5, 0.5, 0.0, 1.0, 1.0, # top right 39 | 0.5, -0.5, 0.0, 1.0, 0.0, # bottom right 40 | -0.5, -0.5, 0.0, 0.0, 0.0, # bottom left 41 | -0.5, 0.5, 0.0, 0.0, 1.0, # top left 42 | ] 43 | vertices = (c_float * len(vertices))(*vertices) 44 | 45 | indices = [ 46 | 0, 1, 3, 47 | 1, 2, 3 48 | ] 49 | indices = (c_uint * len(indices))(*indices) 50 | 51 | vao = gl.glGenVertexArrays(1) 52 | gl.glBindVertexArray(vao) 53 | 54 | vbo = gl.glGenBuffers(1) 55 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 56 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 57 | 58 | ebo = gl.glGenBuffers(1) 59 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 60 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 61 | 62 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) 63 | gl.glEnableVertexAttribArray(0) 64 | 65 | gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 66 | gl.glEnableVertexAttribArray(1) 67 | 68 | # -- load texture 1 69 | texture1 = gl.glGenTextures(1) 70 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 71 | # -- texture wrapping 72 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 73 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 74 | # -- texture filterting 75 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 76 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 77 | 78 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 79 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 80 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 81 | 82 | # -- load texture 2 83 | texture2 = gl.glGenTextures(1) 84 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 85 | # -- texture wrapping 86 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 87 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 88 | # -- texture filterting 89 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 90 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 91 | 92 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 93 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 94 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 95 | 96 | shader.use() 97 | shader.set_int("texture1", 0) 98 | shader.set_int("texture2", 1) 99 | 100 | while not glfw.window_should_close(window): 101 | process_input(window) 102 | 103 | gl.glClearColor(.2, .3, .3, 1.0) 104 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 105 | 106 | gl.glActiveTexture(gl.GL_TEXTURE0) 107 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 108 | gl.glActiveTexture(gl.GL_TEXTURE1) 109 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 110 | 111 | translation = Matrix44.from_translation([0.5, -0.5, 0.0]) 112 | rotation = Matrix44.from_z_rotation(glfw.get_time()) 113 | transform = translation * rotation 114 | 115 | shader.use() 116 | shader.set_mat4('transform', transform) 117 | gl.glBindVertexArray(vao) 118 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 119 | 120 | # -- second container 121 | translation = Matrix44.from_translation([-0.5, 0.5, 0.0]) 122 | scale = Matrix44.from_scale([math.sin(glfw.get_time())]*3) 123 | transform = translation * scale 124 | 125 | shader.set_mat4('transform', transform) 126 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 127 | 128 | glfw.poll_events() 129 | glfw.swap_buffers(window) 130 | 131 | gl.glDeleteVertexArrays(1, id(vao)) 132 | gl.glDeleteBuffers(1, id(vbo)) 133 | gl.glDeleteBuffers(1, id(ebo)) 134 | glfw.terminate() 135 | 136 | 137 | def on_resize(window, w, h): 138 | gl.glViewport(0, 0, w, h) 139 | 140 | 141 | def process_input(window): 142 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 143 | glfw.set_window_should_close(window, True) 144 | 145 | 146 | if __name__ == '__main__': 147 | main() 148 | -------------------------------------------------------------------------------- /source/1.getting_started/6.1.coordinate_systems.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import glfw 4 | import OpenGL.GL as gl 5 | from PIL import Image 6 | from pathlib import Path 7 | from pyrr import Matrix44 8 | from ctypes import c_uint, c_float, sizeof, c_void_p 9 | 10 | CURDIR = Path(__file__).parent.absolute() 11 | RESDIR = CURDIR.parent.parent.joinpath("resources") 12 | sys.path.append(str(CURDIR.parent)) 13 | from shader import Shader 14 | 15 | 16 | def Tex(fn): 17 | return RESDIR.joinpath("textures", fn) 18 | 19 | 20 | width, height = 800, 600 21 | 22 | 23 | def main(): 24 | glfw.init() 25 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 26 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 27 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 28 | 29 | window = glfw.create_window(width, height, "LearnOpenGL", None, None) 30 | if not window: 31 | print("Window Creation failed!") 32 | glfw.terminate() 33 | 34 | glfw.make_context_current(window) 35 | glfw.set_window_size_callback(window, on_resize) 36 | 37 | shader = Shader(CURDIR / 'shaders/6.1.coordinate_systems.vs', CURDIR / 'shaders/6.1.coordinate_systems.fs') 38 | 39 | vertices = [ 40 | # positions tex_coords 41 | 0.5, 0.5, 0.0, 1.0, 1.0, # top right 42 | 0.5, -0.5, 0.0, 1.0, 0.0, # bottom right 43 | -0.5, -0.5, 0.0, 0.0, 0.0, # bottom left 44 | -0.5, 0.5, 0.0, 0.0, 1.0, # top left 45 | ] 46 | vertices = (c_float * len(vertices))(*vertices) 47 | 48 | indices = [ 49 | 0, 1, 3, 50 | 1, 2, 3 51 | ] 52 | indices = (c_uint * len(indices))(*indices) 53 | 54 | vao = gl.glGenVertexArrays(1) 55 | gl.glBindVertexArray(vao) 56 | 57 | vbo = gl.glGenBuffers(1) 58 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 59 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 60 | 61 | ebo = gl.glGenBuffers(1) 62 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ebo) 63 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, gl.GL_STATIC_DRAW) 64 | 65 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) 66 | gl.glEnableVertexAttribArray(0) 67 | 68 | gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 69 | gl.glEnableVertexAttribArray(1) 70 | 71 | # -- load texture 1 72 | texture1 = gl.glGenTextures(1) 73 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 74 | # -- texture wrapping 75 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 76 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 77 | # -- texture filterting 78 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 79 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 80 | 81 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 82 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 83 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 84 | 85 | # -- load texture 2 86 | texture2 = gl.glGenTextures(1) 87 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 88 | # -- texture wrapping 89 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 90 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 91 | # -- texture filterting 92 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 93 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 94 | 95 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 96 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 97 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 98 | 99 | shader.use() 100 | shader.set_int("texture1", 0) 101 | shader.set_int("texture2", 1) 102 | 103 | while not glfw.window_should_close(window): 104 | process_input(window) 105 | 106 | gl.glClearColor(.2, .3, .3, 1.0) 107 | gl.glClear(gl.GL_COLOR_BUFFER_BIT) 108 | 109 | gl.glActiveTexture(gl.GL_TEXTURE0) 110 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 111 | gl.glActiveTexture(gl.GL_TEXTURE1) 112 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 113 | 114 | shader.use() 115 | model = Matrix44.from_x_rotation(math.radians(45)) 116 | view = Matrix44.from_translation([0, 0, -3]) 117 | projection = Matrix44.perspective_projection(45, width/height, 0.1, 100.0) 118 | 119 | shader.set_mat4('view', view) 120 | shader.set_mat4('model', model) 121 | shader.set_mat4('projection', projection) 122 | gl.glBindVertexArray(vao) 123 | gl.glDrawElements(gl.GL_TRIANGLES, 6, gl.GL_UNSIGNED_INT, c_void_p(0)) 124 | 125 | glfw.poll_events() 126 | glfw.swap_buffers(window) 127 | 128 | gl.glDeleteVertexArrays(1, id(vao)) 129 | gl.glDeleteBuffers(1, id(vbo)) 130 | gl.glDeleteBuffers(1, id(ebo)) 131 | glfw.terminate() 132 | 133 | 134 | def on_resize(window, w, h): 135 | gl.glViewport(0, 0, w, h) 136 | 137 | 138 | def process_input(window): 139 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 140 | glfw.set_window_should_close(window, True) 141 | 142 | 143 | if __name__ == '__main__': 144 | main() 145 | -------------------------------------------------------------------------------- /source/1.getting_started/6.2.coordinate_systems_depth.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from PIL import Image 5 | from pathlib import Path 6 | from pyrr import Matrix44 7 | from ctypes import c_float, sizeof, c_void_p 8 | 9 | CURDIR = Path(__file__).parent.absolute() 10 | RESDIR = CURDIR.parent.parent.joinpath("resources") 11 | sys.path.append(str(CURDIR.parent)) 12 | from shader import Shader 13 | 14 | 15 | def Tex(fn): 16 | return RESDIR.joinpath("textures", fn) 17 | 18 | 19 | width, height = 800, 600 20 | 21 | 22 | def main(): 23 | glfw.init() 24 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 25 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 26 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 27 | 28 | window = glfw.create_window(width, height, "LearnOpenGL", None, None) 29 | if not window: 30 | print("Window Creation failed!") 31 | glfw.terminate() 32 | 33 | glfw.make_context_current(window) 34 | glfw.set_window_size_callback(window, on_resize) 35 | 36 | gl.glEnable(gl.GL_DEPTH_TEST) 37 | shader = Shader(CURDIR / 'shaders/6.1.coordinate_systems.vs', CURDIR / 'shaders/6.1.coordinate_systems.fs') 38 | 39 | vertices = [ 40 | # positions tex_coords 41 | -0.5, -0.5, -0.5, 0.0, 0.0, 42 | 0.5, -0.5, -0.5, 1.0, 0.0, 43 | 0.5, 0.5, -0.5, 1.0, 1.0, 44 | 0.5, 0.5, -0.5, 1.0, 1.0, 45 | -0.5, 0.5, -0.5, 0.0, 1.0, 46 | -0.5, -0.5, -0.5, 0.0, 0.0, 47 | 48 | -0.5, -0.5, 0.5, 0.0, 0.0, 49 | 0.5, -0.5, 0.5, 1.0, 0.0, 50 | 0.5, 0.5, 0.5, 1.0, 1.0, 51 | 0.5, 0.5, 0.5, 1.0, 1.0, 52 | -0.5, 0.5, 0.5, 0.0, 1.0, 53 | -0.5, -0.5, 0.5, 0.0, 0.0, 54 | 55 | -0.5, 0.5, 0.5, 1.0, 0.0, 56 | -0.5, 0.5, -0.5, 1.0, 1.0, 57 | -0.5, -0.5, -0.5, 0.0, 1.0, 58 | -0.5, -0.5, -0.5, 0.0, 1.0, 59 | -0.5, -0.5, 0.5, 0.0, 0.0, 60 | -0.5, 0.5, 0.5, 1.0, 0.0, 61 | 62 | 0.5, 0.5, 0.5, 1.0, 0.0, 63 | 0.5, 0.5, -0.5, 1.0, 1.0, 64 | 0.5, -0.5, -0.5, 0.0, 1.0, 65 | 0.5, -0.5, -0.5, 0.0, 1.0, 66 | 0.5, -0.5, 0.5, 0.0, 0.0, 67 | 0.5, 0.5, 0.5, 1.0, 0.0, 68 | 69 | -0.5, -0.5, -0.5, 0.0, 1.0, 70 | 0.5, -0.5, -0.5, 1.0, 1.0, 71 | 0.5, -0.5, 0.5, 1.0, 0.0, 72 | 0.5, -0.5, 0.5, 1.0, 0.0, 73 | -0.5, -0.5, 0.5, 0.0, 0.0, 74 | -0.5, -0.5, -0.5, 0.0, 1.0, 75 | 76 | -0.5, 0.5, -0.5, 0.0, 1.0, 77 | 0.5, 0.5, -0.5, 1.0, 1.0, 78 | 0.5, 0.5, 0.5, 1.0, 0.0, 79 | 0.5, 0.5, 0.5, 1.0, 0.0, 80 | -0.5, 0.5, 0.5, 0.0, 0.0, 81 | -0.5, 0.5, -0.5, 0.0, 1.0 82 | ] 83 | vertices = (c_float * len(vertices))(*vertices) 84 | 85 | vao = gl.glGenVertexArrays(1) 86 | gl.glBindVertexArray(vao) 87 | 88 | vbo = gl.glGenBuffers(1) 89 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 90 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 91 | 92 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) 93 | gl.glEnableVertexAttribArray(0) 94 | 95 | gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 96 | gl.glEnableVertexAttribArray(1) 97 | 98 | # -- load texture 1 99 | texture1 = gl.glGenTextures(1) 100 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 101 | # -- texture wrapping 102 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 103 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 104 | # -- texture filterting 105 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 106 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 107 | 108 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 109 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 110 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 111 | 112 | # -- load texture 2 113 | texture2 = gl.glGenTextures(1) 114 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 115 | # -- texture wrapping 116 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 117 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 118 | # -- texture filterting 119 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 120 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 121 | 122 | img = Image.open(Tex('awesomeface.png')).transpose(Image.FLIP_TOP_BOTTOM) 123 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 124 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 125 | 126 | shader.use() 127 | shader.set_int("texture1", 0) 128 | shader.set_int("texture2", 1) 129 | 130 | while not glfw.window_should_close(window): 131 | process_input(window) 132 | 133 | gl.glClearColor(.2, .3, .3, 1.0) 134 | gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 135 | 136 | gl.glActiveTexture(gl.GL_TEXTURE0) 137 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 138 | gl.glActiveTexture(gl.GL_TEXTURE1) 139 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 140 | 141 | shader.use() 142 | model = Matrix44.from_x_rotation(glfw.get_time() * 0.5) * Matrix44.from_y_rotation(glfw.get_time()) 143 | view = Matrix44.from_translation([0, 0, -3]) 144 | projection = Matrix44.perspective_projection(45, width/height, 0.1, 100.0) 145 | 146 | shader.set_mat4('view', view) 147 | shader.set_mat4('model', model) 148 | shader.set_mat4('projection', projection) 149 | gl.glBindVertexArray(vao) 150 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) 151 | 152 | glfw.poll_events() 153 | glfw.swap_buffers(window) 154 | 155 | gl.glDeleteVertexArrays(1, id(vao)) 156 | gl.glDeleteBuffers(1, id(vbo)) 157 | glfw.terminate() 158 | 159 | 160 | def on_resize(window, w, h): 161 | gl.glViewport(0, 0, w, h) 162 | 163 | 164 | def process_input(window): 165 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 166 | glfw.set_window_should_close(window, True) 167 | 168 | 169 | if __name__ == '__main__': 170 | main() 171 | -------------------------------------------------------------------------------- /source/1.getting_started/6.3.coordinate_systems_multiple.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import glfw 4 | import OpenGL.GL as gl 5 | from PIL import Image 6 | from pathlib import Path 7 | from pyrr import Matrix44, matrix44 8 | from ctypes import c_float, sizeof, c_void_p 9 | 10 | CURDIR = Path(__file__).parent.absolute() 11 | RESDIR = CURDIR.parent.parent.joinpath("resources") 12 | sys.path.append(str(CURDIR.parent)) 13 | from shader import Shader 14 | 15 | 16 | def Tex(fn): 17 | return RESDIR.joinpath("textures", fn) 18 | 19 | 20 | width, height = 800, 600 21 | 22 | 23 | def main(): 24 | glfw.init() 25 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 26 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 27 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 28 | 29 | window = glfw.create_window(width, height, "LearnOpenGL", None, None) 30 | if not window: 31 | print("Window Creation failed!") 32 | glfw.terminate() 33 | 34 | glfw.make_context_current(window) 35 | glfw.set_window_size_callback(window, on_resize) 36 | 37 | gl.glEnable(gl.GL_DEPTH_TEST) 38 | shader = Shader(CURDIR / 'shaders/6.1.coordinate_systems.vs', CURDIR / 'shaders/6.1.coordinate_systems.fs') 39 | 40 | vertices = [ 41 | # positions tex_coords 42 | -0.5, -0.5, -0.5, 0.0, 0.0, 43 | 0.5, -0.5, -0.5, 1.0, 0.0, 44 | 0.5, 0.5, -0.5, 1.0, 1.0, 45 | 0.5, 0.5, -0.5, 1.0, 1.0, 46 | -0.5, 0.5, -0.5, 0.0, 1.0, 47 | -0.5, -0.5, -0.5, 0.0, 0.0, 48 | 49 | -0.5, -0.5, 0.5, 0.0, 0.0, 50 | 0.5, -0.5, 0.5, 1.0, 0.0, 51 | 0.5, 0.5, 0.5, 1.0, 1.0, 52 | 0.5, 0.5, 0.5, 1.0, 1.0, 53 | -0.5, 0.5, 0.5, 0.0, 1.0, 54 | -0.5, -0.5, 0.5, 0.0, 0.0, 55 | 56 | -0.5, 0.5, 0.5, 1.0, 0.0, 57 | -0.5, 0.5, -0.5, 1.0, 1.0, 58 | -0.5, -0.5, -0.5, 0.0, 1.0, 59 | -0.5, -0.5, -0.5, 0.0, 1.0, 60 | -0.5, -0.5, 0.5, 0.0, 0.0, 61 | -0.5, 0.5, 0.5, 1.0, 0.0, 62 | 63 | 0.5, 0.5, 0.5, 1.0, 0.0, 64 | 0.5, 0.5, -0.5, 1.0, 1.0, 65 | 0.5, -0.5, -0.5, 0.0, 1.0, 66 | 0.5, -0.5, -0.5, 0.0, 1.0, 67 | 0.5, -0.5, 0.5, 0.0, 0.0, 68 | 0.5, 0.5, 0.5, 1.0, 0.0, 69 | 70 | -0.5, -0.5, -0.5, 0.0, 1.0, 71 | 0.5, -0.5, -0.5, 1.0, 1.0, 72 | 0.5, -0.5, 0.5, 1.0, 0.0, 73 | 0.5, -0.5, 0.5, 1.0, 0.0, 74 | -0.5, -0.5, 0.5, 0.0, 0.0, 75 | -0.5, -0.5, -0.5, 0.0, 1.0, 76 | 77 | -0.5, 0.5, -0.5, 0.0, 1.0, 78 | 0.5, 0.5, -0.5, 1.0, 1.0, 79 | 0.5, 0.5, 0.5, 1.0, 0.0, 80 | 0.5, 0.5, 0.5, 1.0, 0.0, 81 | -0.5, 0.5, 0.5, 0.0, 0.0, 82 | -0.5, 0.5, -0.5, 0.0, 1.0 83 | ] 84 | vertices = (c_float * len(vertices))(*vertices) 85 | 86 | cube_positions = [ 87 | ( 0.0, 0.0, 0.0), 88 | ( 2.0, 5.0, -15.0), 89 | (-1.5, -2.2, -2.5), 90 | (-3.8, -2.0, -12.3), 91 | ( 2.4, -0.4, -3.5), 92 | (-1.7, 3.0, -7.5), 93 | ( 1.3, -2.0, -2.5), 94 | ( 1.5, 2.0, -2.5), 95 | ( 1.5, 0.2, -1.5), 96 | (-1.3, 1.0, -1.5) 97 | ] 98 | 99 | 100 | vao = gl.glGenVertexArrays(1) 101 | gl.glBindVertexArray(vao) 102 | 103 | vbo = gl.glGenBuffers(1) 104 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 105 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 106 | 107 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) 108 | gl.glEnableVertexAttribArray(0) 109 | 110 | gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 111 | gl.glEnableVertexAttribArray(1) 112 | 113 | # -- load texture 1 114 | texture1 = gl.glGenTextures(1) 115 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 116 | # -- texture wrapping 117 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 118 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 119 | # -- texture filterting 120 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 121 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 122 | 123 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 124 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 125 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 126 | 127 | # -- load texture 2 128 | texture2 = gl.glGenTextures(1) 129 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 130 | # -- texture wrapping 131 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 132 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 133 | # -- texture filterting 134 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 135 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 136 | 137 | img = Image.open(Tex('awesomeface.png')) 138 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 139 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 140 | 141 | shader.use() 142 | shader.set_int("texture1", 0) 143 | shader.set_int("texture2", 1) 144 | 145 | while not glfw.window_should_close(window): 146 | process_input(window) 147 | 148 | gl.glClearColor(.2, .3, .3, 1.0) 149 | gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 150 | 151 | gl.glActiveTexture(gl.GL_TEXTURE0) 152 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 153 | gl.glActiveTexture(gl.GL_TEXTURE1) 154 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 155 | 156 | shader.use() 157 | view = Matrix44.from_translation([0, 0, -3]) 158 | projection = Matrix44.perspective_projection(45, width/height, 0.1, 100.0) 159 | 160 | shader.set_mat4('view', view) 161 | shader.set_mat4('projection', projection) 162 | 163 | gl.glBindVertexArray(vao) 164 | for idx, position in enumerate(cube_positions): 165 | angle = 20.0 * idx 166 | rotation = matrix44.create_from_axis_rotation([1.0, 0.3, 0.5], math.radians(angle)) 167 | translation = Matrix44.from_translation(position) 168 | model = translation * rotation 169 | shader.set_mat4('model', model) 170 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) 171 | 172 | glfw.poll_events() 173 | glfw.swap_buffers(window) 174 | 175 | gl.glDeleteVertexArrays(1, id(vao)) 176 | gl.glDeleteBuffers(1, id(vbo)) 177 | glfw.terminate() 178 | 179 | 180 | def on_resize(window, w, h): 181 | gl.glViewport(0, 0, w, h) 182 | 183 | 184 | def process_input(window): 185 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 186 | glfw.set_window_should_close(window, True) 187 | 188 | 189 | if __name__ == '__main__': 190 | main() 191 | -------------------------------------------------------------------------------- /source/1.getting_started/6.4.coordinate_systems_exercise1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import glfw 4 | import OpenGL.GL as gl 5 | from PIL import Image 6 | from pathlib import Path 7 | from pyrr import Matrix44, matrix44 8 | from ctypes import c_float, sizeof, c_void_p 9 | 10 | CURDIR = Path(__file__).parent.absolute() 11 | RESDIR = CURDIR.parent.parent.joinpath("resources") 12 | sys.path.append(str(CURDIR.parent)) 13 | from shader import Shader 14 | 15 | 16 | def Tex(fn): 17 | return RESDIR.joinpath("textures", fn) 18 | 19 | 20 | width, height = 800, 600 21 | 22 | 23 | def main(): 24 | glfw.init() 25 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 26 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 27 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 28 | 29 | window = glfw.create_window(width, height, "LearnOpenGL", None, None) 30 | if not window: 31 | print("Window Creation failed!") 32 | glfw.terminate() 33 | 34 | glfw.make_context_current(window) 35 | glfw.set_window_size_callback(window, on_resize) 36 | 37 | gl.glEnable(gl.GL_DEPTH_TEST) 38 | shader = Shader(CURDIR / 'shaders/6.1.coordinate_systems.vs', CURDIR / 'shaders/6.1.coordinate_systems.fs') 39 | 40 | vertices = [ 41 | # positions tex_coords 42 | -0.5, -0.5, -0.5, 0.0, 0.0, 43 | 0.5, -0.5, -0.5, 1.0, 0.0, 44 | 0.5, 0.5, -0.5, 1.0, 1.0, 45 | 0.5, 0.5, -0.5, 1.0, 1.0, 46 | -0.5, 0.5, -0.5, 0.0, 1.0, 47 | -0.5, -0.5, -0.5, 0.0, 0.0, 48 | 49 | -0.5, -0.5, 0.5, 0.0, 0.0, 50 | 0.5, -0.5, 0.5, 1.0, 0.0, 51 | 0.5, 0.5, 0.5, 1.0, 1.0, 52 | 0.5, 0.5, 0.5, 1.0, 1.0, 53 | -0.5, 0.5, 0.5, 0.0, 1.0, 54 | -0.5, -0.5, 0.5, 0.0, 0.0, 55 | 56 | -0.5, 0.5, 0.5, 1.0, 0.0, 57 | -0.5, 0.5, -0.5, 1.0, 1.0, 58 | -0.5, -0.5, -0.5, 0.0, 1.0, 59 | -0.5, -0.5, -0.5, 0.0, 1.0, 60 | -0.5, -0.5, 0.5, 0.0, 0.0, 61 | -0.5, 0.5, 0.5, 1.0, 0.0, 62 | 63 | 0.5, 0.5, 0.5, 1.0, 0.0, 64 | 0.5, 0.5, -0.5, 1.0, 1.0, 65 | 0.5, -0.5, -0.5, 0.0, 1.0, 66 | 0.5, -0.5, -0.5, 0.0, 1.0, 67 | 0.5, -0.5, 0.5, 0.0, 0.0, 68 | 0.5, 0.5, 0.5, 1.0, 0.0, 69 | 70 | -0.5, -0.5, -0.5, 0.0, 1.0, 71 | 0.5, -0.5, -0.5, 1.0, 1.0, 72 | 0.5, -0.5, 0.5, 1.0, 0.0, 73 | 0.5, -0.5, 0.5, 1.0, 0.0, 74 | -0.5, -0.5, 0.5, 0.0, 0.0, 75 | -0.5, -0.5, -0.5, 0.0, 1.0, 76 | 77 | -0.5, 0.5, -0.5, 0.0, 1.0, 78 | 0.5, 0.5, -0.5, 1.0, 1.0, 79 | 0.5, 0.5, 0.5, 1.0, 0.0, 80 | 0.5, 0.5, 0.5, 1.0, 0.0, 81 | -0.5, 0.5, 0.5, 0.0, 0.0, 82 | -0.5, 0.5, -0.5, 0.0, 1.0 83 | ] 84 | vertices = (c_float * len(vertices))(*vertices) 85 | 86 | cube_positions = [ 87 | ( 0.0, 0.0, 0.0), 88 | ( 2.0, 5.0, -15.0), 89 | (-1.5, -2.2, -2.5), 90 | (-3.8, -2.0, -12.3), 91 | ( 2.4, -0.4, -3.5), 92 | (-1.7, 3.0, -7.5), 93 | ( 1.3, -2.0, -2.5), 94 | ( 1.5, 2.0, -2.5), 95 | ( 1.5, 0.2, -1.5), 96 | (-1.3, 1.0, -1.5) 97 | ] 98 | 99 | vao = gl.glGenVertexArrays(1) 100 | gl.glBindVertexArray(vao) 101 | 102 | vbo = gl.glGenBuffers(1) 103 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 104 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 105 | 106 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) 107 | gl.glEnableVertexAttribArray(0) 108 | 109 | gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 110 | gl.glEnableVertexAttribArray(1) 111 | 112 | # -- load texture 1 113 | texture1 = gl.glGenTextures(1) 114 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 115 | # -- texture wrapping 116 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 117 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 118 | # -- texture filterting 119 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 120 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 121 | 122 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 123 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 124 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 125 | 126 | # -- load texture 2 127 | texture2 = gl.glGenTextures(1) 128 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 129 | # -- texture wrapping 130 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 131 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 132 | # -- texture filterting 133 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 134 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 135 | 136 | img = Image.open(Tex('awesomeface.png')) 137 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 138 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 139 | 140 | shader.use() 141 | shader.set_int("texture1", 0) 142 | shader.set_int("texture2", 1) 143 | 144 | while not glfw.window_should_close(window): 145 | process_input(window) 146 | 147 | gl.glClearColor(.2, .3, .3, 1.0) 148 | gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 149 | 150 | gl.glActiveTexture(gl.GL_TEXTURE0) 151 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 152 | gl.glActiveTexture(gl.GL_TEXTURE1) 153 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 154 | 155 | shader.use() 156 | view = Matrix44.from_translation([0, 0, -3]) 157 | projection = Matrix44.perspective_projection(45, width/height, 0.1, 100.0) 158 | 159 | shader.set_mat4('view', view) 160 | shader.set_mat4('projection', projection) 161 | 162 | gl.glBindVertexArray(vao) 163 | for idx, position in enumerate(cube_positions): 164 | angle = math.radians(20.0 * idx) 165 | if idx % 3 == 0: 166 | angle = glfw.get_time() 167 | 168 | rotation = matrix44.create_from_axis_rotation([1.0, 0.3, 0.5], angle) 169 | translation = Matrix44.from_translation(position) 170 | model = translation * rotation 171 | shader.set_mat4('model', model) 172 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) 173 | 174 | glfw.poll_events() 175 | glfw.swap_buffers(window) 176 | 177 | gl.glDeleteVertexArrays(1, id(vao)) 178 | gl.glDeleteBuffers(1, id(vbo)) 179 | glfw.terminate() 180 | 181 | 182 | def on_resize(window, w, h): 183 | gl.glViewport(0, 0, w, h) 184 | 185 | 186 | def process_input(window): 187 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 188 | glfw.set_window_should_close(window, True) 189 | 190 | 191 | if __name__ == '__main__': 192 | main() 193 | -------------------------------------------------------------------------------- /source/1.getting_started/7.1.camera_circle.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import glfw 4 | import OpenGL.GL as gl 5 | from PIL import Image 6 | from pathlib import Path 7 | from pyrr import Matrix44, matrix44 8 | from ctypes import c_float, sizeof, c_void_p 9 | 10 | CURDIR = Path(__file__).parent.absolute() 11 | RESDIR = CURDIR.parent.parent.joinpath("resources") 12 | sys.path.append(str(CURDIR.parent)) 13 | from shader import Shader 14 | 15 | 16 | def Tex(fn): 17 | return RESDIR.joinpath("textures", fn) 18 | 19 | 20 | width, height = 800, 600 21 | 22 | 23 | def main(): 24 | glfw.init() 25 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 26 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 27 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 28 | 29 | window = glfw.create_window(width, height, "LearnOpenGL", None, None) 30 | if not window: 31 | print("Window Creation failed!") 32 | glfw.terminate() 33 | 34 | glfw.make_context_current(window) 35 | glfw.set_window_size_callback(window, on_resize) 36 | 37 | gl.glEnable(gl.GL_DEPTH_TEST) 38 | shader = Shader(CURDIR / 'shaders/6.1.coordinate_systems.vs', CURDIR / 'shaders/6.1.coordinate_systems.fs') 39 | 40 | vertices = [ 41 | # positions tex_coords 42 | -0.5, -0.5, -0.5, 0.0, 0.0, 43 | 0.5, -0.5, -0.5, 1.0, 0.0, 44 | 0.5, 0.5, -0.5, 1.0, 1.0, 45 | 0.5, 0.5, -0.5, 1.0, 1.0, 46 | -0.5, 0.5, -0.5, 0.0, 1.0, 47 | -0.5, -0.5, -0.5, 0.0, 0.0, 48 | 49 | -0.5, -0.5, 0.5, 0.0, 0.0, 50 | 0.5, -0.5, 0.5, 1.0, 0.0, 51 | 0.5, 0.5, 0.5, 1.0, 1.0, 52 | 0.5, 0.5, 0.5, 1.0, 1.0, 53 | -0.5, 0.5, 0.5, 0.0, 1.0, 54 | -0.5, -0.5, 0.5, 0.0, 0.0, 55 | 56 | -0.5, 0.5, 0.5, 1.0, 0.0, 57 | -0.5, 0.5, -0.5, 1.0, 1.0, 58 | -0.5, -0.5, -0.5, 0.0, 1.0, 59 | -0.5, -0.5, -0.5, 0.0, 1.0, 60 | -0.5, -0.5, 0.5, 0.0, 0.0, 61 | -0.5, 0.5, 0.5, 1.0, 0.0, 62 | 63 | 0.5, 0.5, 0.5, 1.0, 0.0, 64 | 0.5, 0.5, -0.5, 1.0, 1.0, 65 | 0.5, -0.5, -0.5, 0.0, 1.0, 66 | 0.5, -0.5, -0.5, 0.0, 1.0, 67 | 0.5, -0.5, 0.5, 0.0, 0.0, 68 | 0.5, 0.5, 0.5, 1.0, 0.0, 69 | 70 | -0.5, -0.5, -0.5, 0.0, 1.0, 71 | 0.5, -0.5, -0.5, 1.0, 1.0, 72 | 0.5, -0.5, 0.5, 1.0, 0.0, 73 | 0.5, -0.5, 0.5, 1.0, 0.0, 74 | -0.5, -0.5, 0.5, 0.0, 0.0, 75 | -0.5, -0.5, -0.5, 0.0, 1.0, 76 | 77 | -0.5, 0.5, -0.5, 0.0, 1.0, 78 | 0.5, 0.5, -0.5, 1.0, 1.0, 79 | 0.5, 0.5, 0.5, 1.0, 0.0, 80 | 0.5, 0.5, 0.5, 1.0, 0.0, 81 | -0.5, 0.5, 0.5, 0.0, 0.0, 82 | -0.5, 0.5, -0.5, 0.0, 1.0 83 | ] 84 | vertices = (c_float * len(vertices))(*vertices) 85 | 86 | cube_positions = [ 87 | ( 0.0, 0.0, 0.0), 88 | ( 2.0, 5.0, -15.0), 89 | (-1.5, -2.2, -2.5), 90 | (-3.8, -2.0, -12.3), 91 | ( 2.4, -0.4, -3.5), 92 | (-1.7, 3.0, -7.5), 93 | ( 1.3, -2.0, -2.5), 94 | ( 1.5, 2.0, -2.5), 95 | ( 1.5, 0.2, -1.5), 96 | (-1.3, 1.0, -1.5) 97 | ] 98 | 99 | vao = gl.glGenVertexArrays(1) 100 | gl.glBindVertexArray(vao) 101 | 102 | vbo = gl.glGenBuffers(1) 103 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 104 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 105 | 106 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) 107 | gl.glEnableVertexAttribArray(0) 108 | 109 | gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 110 | gl.glEnableVertexAttribArray(1) 111 | 112 | # -- load texture 1 113 | texture1 = gl.glGenTextures(1) 114 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 115 | # -- texture wrapping 116 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 117 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 118 | # -- texture filterting 119 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 120 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 121 | 122 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 123 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 124 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 125 | 126 | # -- load texture 2 127 | texture2 = gl.glGenTextures(1) 128 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 129 | # -- texture wrapping 130 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 131 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 132 | # -- texture filterting 133 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 134 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 135 | 136 | img = Image.open(Tex('awesomeface.png')) 137 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 138 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 139 | 140 | shader.use() 141 | shader.set_int("texture1", 0) 142 | shader.set_int("texture2", 1) 143 | 144 | projection = Matrix44.perspective_projection(45, width/height, 0.1, 100.0) 145 | shader.set_mat4('projection', projection) 146 | 147 | while not glfw.window_should_close(window): 148 | process_input(window) 149 | 150 | gl.glClearColor(.2, .3, .3, 1.0) 151 | gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 152 | 153 | gl.glActiveTexture(gl.GL_TEXTURE0) 154 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 155 | gl.glActiveTexture(gl.GL_TEXTURE1) 156 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 157 | 158 | shader.use() 159 | radius = 10.0 160 | camx = math.sin(glfw.get_time()) * radius 161 | camz = math.cos(glfw.get_time()) * radius 162 | view = Matrix44.look_at([camx, 0.0, camz], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0]) 163 | shader.set_mat4('view', view) 164 | 165 | gl.glBindVertexArray(vao) 166 | for idx, position in enumerate(cube_positions): 167 | angle = 20.0 * idx 168 | rotation = matrix44.create_from_axis_rotation([1.0, 0.3, 0.5], math.radians(angle)) 169 | translation = Matrix44.from_translation(position) 170 | model = translation * rotation 171 | shader.set_mat4('model', model) 172 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) 173 | 174 | glfw.poll_events() 175 | glfw.swap_buffers(window) 176 | 177 | gl.glDeleteVertexArrays(1, id(vao)) 178 | gl.glDeleteBuffers(1, id(vbo)) 179 | glfw.terminate() 180 | 181 | 182 | def on_resize(window, w, h): 183 | gl.glViewport(0, 0, w, h) 184 | 185 | 186 | def process_input(window): 187 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 188 | glfw.set_window_should_close(window, True) 189 | 190 | 191 | if __name__ == '__main__': 192 | main() 193 | -------------------------------------------------------------------------------- /source/1.getting_started/7.2.camera_keyboard_dt.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import glfw 4 | import OpenGL.GL as gl 5 | from PIL import Image 6 | from pathlib import Path 7 | from pyrr import Matrix44, matrix44, Vector3 8 | from ctypes import c_float, sizeof, c_void_p 9 | 10 | CURDIR = Path(__file__).parent.absolute() 11 | RESDIR = CURDIR.parent.parent.joinpath("resources") 12 | sys.path.append(str(CURDIR.parent)) 13 | from shader import Shader 14 | 15 | 16 | def Tex(fn): 17 | return RESDIR.joinpath("textures", fn) 18 | 19 | 20 | width, height = 800, 600 21 | camera_pos = Vector3([0.0, 0.0, 3.0]) 22 | camera_front = Vector3([0.0, 0.0, -1.0]) 23 | camera_up = Vector3([0.0, 1.0, 0.0]) 24 | 25 | delta_time = 0.0 26 | last_frame = 0.0 27 | 28 | 29 | def main(): 30 | global delta_time, last_frame 31 | 32 | glfw.init() 33 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 34 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 35 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 36 | 37 | window = glfw.create_window(width, height, "LearnOpenGL", None, None) 38 | if not window: 39 | print("Window Creation failed!") 40 | glfw.terminate() 41 | 42 | glfw.make_context_current(window) 43 | glfw.set_window_size_callback(window, on_resize) 44 | 45 | gl.glEnable(gl.GL_DEPTH_TEST) 46 | shader = Shader(CURDIR / 'shaders/6.1.coordinate_systems.vs', CURDIR / 'shaders/6.1.coordinate_systems.fs') 47 | 48 | vertices = [ 49 | # positions tex_coords 50 | -0.5, -0.5, -0.5, 0.0, 0.0, 51 | 0.5, -0.5, -0.5, 1.0, 0.0, 52 | 0.5, 0.5, -0.5, 1.0, 1.0, 53 | 0.5, 0.5, -0.5, 1.0, 1.0, 54 | -0.5, 0.5, -0.5, 0.0, 1.0, 55 | -0.5, -0.5, -0.5, 0.0, 0.0, 56 | 57 | -0.5, -0.5, 0.5, 0.0, 0.0, 58 | 0.5, -0.5, 0.5, 1.0, 0.0, 59 | 0.5, 0.5, 0.5, 1.0, 1.0, 60 | 0.5, 0.5, 0.5, 1.0, 1.0, 61 | -0.5, 0.5, 0.5, 0.0, 1.0, 62 | -0.5, -0.5, 0.5, 0.0, 0.0, 63 | 64 | -0.5, 0.5, 0.5, 1.0, 0.0, 65 | -0.5, 0.5, -0.5, 1.0, 1.0, 66 | -0.5, -0.5, -0.5, 0.0, 1.0, 67 | -0.5, -0.5, -0.5, 0.0, 1.0, 68 | -0.5, -0.5, 0.5, 0.0, 0.0, 69 | -0.5, 0.5, 0.5, 1.0, 0.0, 70 | 71 | 0.5, 0.5, 0.5, 1.0, 0.0, 72 | 0.5, 0.5, -0.5, 1.0, 1.0, 73 | 0.5, -0.5, -0.5, 0.0, 1.0, 74 | 0.5, -0.5, -0.5, 0.0, 1.0, 75 | 0.5, -0.5, 0.5, 0.0, 0.0, 76 | 0.5, 0.5, 0.5, 1.0, 0.0, 77 | 78 | -0.5, -0.5, -0.5, 0.0, 1.0, 79 | 0.5, -0.5, -0.5, 1.0, 1.0, 80 | 0.5, -0.5, 0.5, 1.0, 0.0, 81 | 0.5, -0.5, 0.5, 1.0, 0.0, 82 | -0.5, -0.5, 0.5, 0.0, 0.0, 83 | -0.5, -0.5, -0.5, 0.0, 1.0, 84 | 85 | -0.5, 0.5, -0.5, 0.0, 1.0, 86 | 0.5, 0.5, -0.5, 1.0, 1.0, 87 | 0.5, 0.5, 0.5, 1.0, 0.0, 88 | 0.5, 0.5, 0.5, 1.0, 0.0, 89 | -0.5, 0.5, 0.5, 0.0, 0.0, 90 | -0.5, 0.5, -0.5, 0.0, 1.0 91 | ] 92 | vertices = (c_float * len(vertices))(*vertices) 93 | 94 | cube_positions = [ 95 | ( 0.0, 0.0, 0.0), 96 | ( 2.0, 5.0, -15.0), 97 | (-1.5, -2.2, -2.5), 98 | (-3.8, -2.0, -12.3), 99 | ( 2.4, -0.4, -3.5), 100 | (-1.7, 3.0, -7.5), 101 | ( 1.3, -2.0, -2.5), 102 | ( 1.5, 2.0, -2.5), 103 | ( 1.5, 0.2, -1.5), 104 | (-1.3, 1.0, -1.5) 105 | ] 106 | 107 | 108 | vao = gl.glGenVertexArrays(1) 109 | gl.glBindVertexArray(vao) 110 | 111 | vbo = gl.glGenBuffers(1) 112 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 113 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 114 | 115 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(0)) 116 | gl.glEnableVertexAttribArray(0) 117 | 118 | gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, gl.GL_FALSE, 5 * sizeof(c_float), c_void_p(3 * sizeof(c_float))) 119 | gl.glEnableVertexAttribArray(1) 120 | 121 | # -- load texture 1 122 | texture1 = gl.glGenTextures(1) 123 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 124 | # -- texture wrapping 125 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 126 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 127 | # -- texture filterting 128 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 129 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 130 | 131 | img = Image.open(Tex('container.jpg')).transpose(Image.FLIP_TOP_BOTTOM) 132 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, img.tobytes()) 133 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 134 | 135 | # -- load texture 2 136 | texture2 = gl.glGenTextures(1) 137 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 138 | # -- texture wrapping 139 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 140 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 141 | # -- texture filterting 142 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) 143 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 144 | 145 | img = Image.open(Tex('awesomeface.png')) 146 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, img.tobytes()) 147 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 148 | 149 | shader.use() 150 | shader.set_int("texture1", 0) 151 | shader.set_int("texture2", 1) 152 | 153 | projection = Matrix44.perspective_projection(45, width/height, 0.1, 100.0) 154 | shader.set_mat4('projection', projection) 155 | 156 | while not glfw.window_should_close(window): 157 | current_frame = glfw.get_time() 158 | delta_time = current_frame - last_frame 159 | last_frame = current_frame 160 | 161 | process_input(window) 162 | 163 | gl.glClearColor(.2, .3, .3, 1.0) 164 | gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 165 | 166 | gl.glActiveTexture(gl.GL_TEXTURE0) 167 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture1) 168 | gl.glActiveTexture(gl.GL_TEXTURE1) 169 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture2) 170 | 171 | shader.use() 172 | view = Matrix44.look_at(camera_pos, camera_pos + camera_front, camera_up) 173 | shader.set_mat4('view', view) 174 | 175 | gl.glBindVertexArray(vao) 176 | for idx, position in enumerate(cube_positions): 177 | angle = 20.0 * idx 178 | rotation = matrix44.create_from_axis_rotation([1.0, 0.3, 0.5], math.radians(angle)) 179 | translation = Matrix44.from_translation(position) 180 | model = translation * rotation 181 | shader.set_mat4('model', model) 182 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) 183 | 184 | glfw.poll_events() 185 | glfw.swap_buffers(window) 186 | 187 | gl.glDeleteVertexArrays(1, id(vao)) 188 | gl.glDeleteBuffers(1, id(vbo)) 189 | glfw.terminate() 190 | 191 | 192 | def on_resize(window, w, h): 193 | gl.glViewport(0, 0, w, h) 194 | 195 | 196 | def process_input(window): 197 | global camera_pos, camera_front 198 | cam_speed = 2.5 * delta_time 199 | 200 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 201 | glfw.set_window_should_close(window, True) 202 | 203 | if glfw.get_key(window, glfw.KEY_W) == glfw.PRESS: 204 | camera_pos += cam_speed * camera_front 205 | if glfw.get_key(window, glfw.KEY_S) == glfw.PRESS: 206 | camera_pos -= cam_speed * camera_front 207 | 208 | if glfw.get_key(window, glfw.KEY_A) == glfw.PRESS: 209 | camera_pos -= camera_front.cross(camera_up).normalized * cam_speed 210 | if glfw.get_key(window, glfw.KEY_D) == glfw.PRESS: 211 | camera_pos += camera_front.cross(camera_up).normalized * cam_speed 212 | 213 | 214 | if __name__ == '__main__': 215 | main() 216 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/3.3.shader.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | in vec3 ourColor; 4 | out vec4 FragColor; 5 | 6 | void main() { 7 | FragColor = vec4(ourColor, 1.0f); 8 | } 9 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/3.3.shader.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec3 aColor; 5 | 6 | out vec3 ourColor; 7 | 8 | void main() { 9 | gl_Position = vec4(aPos, 1.0); 10 | ourColor = aColor; 11 | } 12 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/3.4.shader.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | in vec3 ourColor; 4 | out vec4 FragColor; 5 | 6 | void main() { 7 | FragColor = vec4(ourColor, 1.0f); 8 | } 9 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/3.4.shader.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec3 aColor; 5 | 6 | out vec3 ourColor; 7 | 8 | void main() { 9 | gl_Position = vec4(aPos * -1.0, 1.0); 10 | ourColor = aColor; 11 | } 12 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/3.5.shader.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | in vec3 ourColor; 4 | out vec4 FragColor; 5 | 6 | void main() { 7 | FragColor = vec4(ourColor, 1.0f); 8 | } 9 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/3.5.shader.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec3 aColor; 5 | 6 | out vec3 ourColor; 7 | uniform float offset; 8 | 9 | void main() { 10 | gl_Position = vec4(aPos.x + offset, aPos.y, aPos.z, 1.0); 11 | ourColor = aColor; 12 | } 13 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/3.6.shader.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | in vec3 ourColor; 4 | out vec4 FragColor; 5 | 6 | void main() { 7 | FragColor = vec4(ourColor, 1.0f); 8 | } 9 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/3.6.shader.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | 5 | out vec3 ourColor; 6 | 7 | void main() { 8 | gl_Position = vec4(aPos, 1.0); 9 | ourColor = aPos; 10 | } 11 | -------------------------------------------------------------------------------- /source/1.getting_started/shaders/4.1.texture.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | in vec3 ourColor; 6 | in vec2 TexCoord; 7 | 8 | uniform sampler2D texture1; 9 | 10 | void main() { 11 | FragColor = texture(texture1, TexCoord); 12 | } -------------------------------------------------------------------------------- /source/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 | gl_Position = vec4(aPos, 1.0); 11 | ourColor = aColor; 12 | TexCoord = aTexCoord; 13 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/4.1.texture_mix.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | in vec3 ourColor; 6 | in vec2 TexCoord; 7 | 8 | uniform sampler2D texture1; 9 | 10 | void main() { 11 | FragColor = texture(texture1, TexCoord) * vec4(ourColor, 1.0); 12 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/4.2.texture.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | in vec3 ourColor; 6 | in vec2 TexCoord; 7 | 8 | uniform sampler2D texture1; 9 | uniform sampler2D texture2; 10 | 11 | void main() { 12 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 13 | } -------------------------------------------------------------------------------- /source/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 | gl_Position = vec4(aPos, 1.0); 11 | ourColor = aColor; 12 | TexCoord = aTexCoord; 13 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/4.3.texture_exercise1.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | in vec3 ourColor; 6 | in vec2 TexCoord; 7 | 8 | uniform sampler2D texture1; 9 | uniform sampler2D texture2; 10 | 11 | void main() { 12 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, vec2(TexCoord.x * -1.0, TexCoord.y)), 0.2); 13 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/4.3.texture_exercise1.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 | gl_Position = vec4(aPos, 1.0); 11 | ourColor = aColor; 12 | TexCoord = aTexCoord; 13 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/4.6.texture_exercise4.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | in vec3 ourColor; 6 | in vec2 TexCoord; 7 | 8 | uniform sampler2D texture1; 9 | uniform sampler2D texture2; 10 | uniform float mix_value; 11 | 12 | void main() { 13 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), mix_value); 14 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/4.6.texture_exercise4.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 | gl_Position = vec4(aPos, 1.0); 11 | ourColor = aColor; 12 | TexCoord = aTexCoord; 13 | } -------------------------------------------------------------------------------- /source/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 | } -------------------------------------------------------------------------------- /source/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 = aTexCoord; 13 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/6.1.coordinate_systems.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | in vec2 TexCoord; 6 | 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() { 11 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 12 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/6.1.coordinate_systems.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 pos; 4 | layout (location = 1) in vec2 texcoord; 5 | 6 | out vec2 TexCoord; 7 | 8 | uniform mat4 model; 9 | uniform mat4 view; 10 | uniform mat4 projection; 11 | 12 | void main() { 13 | gl_Position = projection * view * model * vec4(pos, 1.0); 14 | TexCoord = texcoord; 15 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/7.1.camera.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | in vec2 TexCoord; 6 | 7 | uniform sampler2D texture1; 8 | uniform sampler2D texture2; 9 | 10 | void main() { 11 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 12 | } -------------------------------------------------------------------------------- /source/1.getting_started/shaders/7.1.camera.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 pos; 4 | layout (location = 1) in vec2 texcoord; 5 | 6 | out vec2 TexCoord; 7 | 8 | uniform mat4 model; 9 | uniform mat4 view; 10 | uniform mat4 projection; 11 | 12 | void main() { 13 | gl_Position = projection * view * model * vec4(pos, 1.0); 14 | TexCoord = texcoord; 15 | } -------------------------------------------------------------------------------- /source/2.lighting/1.colors.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from pathlib import Path 5 | from pyrr import Vector3, Matrix44 6 | from ctypes import c_float, sizeof, c_void_p 7 | 8 | CURDIR = Path(__file__).parent.absolute() 9 | sys.path.append(str(CURDIR.parent)) 10 | 11 | from shader import Shader 12 | from camera import Camera, CameraMovement 13 | 14 | # -- settings 15 | SRC_WIDTH = 800 16 | SRC_HEIGHT = 600 17 | 18 | # -- camera 19 | camera = Camera(Vector3([0.0, 0.0, 3.0])) 20 | last_x = SRC_WIDTH / 2 21 | last_y = SRC_HEIGHT / 2 22 | first_mouse = True 23 | 24 | # -- timing 25 | delta_time = 0.0 26 | last_frame = 0.0 27 | 28 | light_pos = Vector3([1.2, 1.0, 2.0]) 29 | 30 | 31 | def main(): 32 | global delta_time, last_frame 33 | 34 | if not glfw.init(): 35 | raise ValueError("Failed to initialize glfw") 36 | 37 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 38 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 39 | 40 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 41 | 42 | window = glfw.create_window(SRC_WIDTH, SRC_HEIGHT, "learnOpenGL", None, None) 43 | if not window: 44 | glfw.terminate() 45 | raise ValueError("Failed to create window") 46 | 47 | glfw.make_context_current(window) 48 | glfw.set_framebuffer_size_callback(window, framebuffer_size_callback) 49 | glfw.set_cursor_pos_callback(window, mouse_callback) 50 | glfw.set_scroll_callback(window, scroll_callback) 51 | 52 | glfw.set_input_mode(window, glfw.CURSOR, glfw.CURSOR_DISABLED) 53 | 54 | gl.glEnable(gl.GL_DEPTH_TEST) 55 | 56 | lamp_shader = Shader(CURDIR / "shaders/1.lamp.vs", CURDIR / "shaders/1.lamp.fs") 57 | lighting_shader = Shader(CURDIR / "shaders/1.colors.vs", CURDIR / "shaders/1.colors.fs") 58 | 59 | vertices = [ 60 | -0.5, -0.5, -0.5, 61 | 0.5, -0.5, -0.5, 62 | 0.5, 0.5, -0.5, 63 | 0.5, 0.5, -0.5, 64 | -0.5, 0.5, -0.5, 65 | -0.5, -0.5, -0.5, 66 | 67 | -0.5, -0.5, 0.5, 68 | 0.5, -0.5, 0.5, 69 | 0.5, 0.5, 0.5, 70 | 0.5, 0.5, 0.5, 71 | -0.5, 0.5, 0.5, 72 | -0.5, -0.5, 0.5, 73 | 74 | -0.5, 0.5, 0.5, 75 | -0.5, 0.5, -0.5, 76 | -0.5, -0.5, -0.5, 77 | -0.5, -0.5, -0.5, 78 | -0.5, -0.5, 0.5, 79 | -0.5, 0.5, 0.5, 80 | 81 | 0.5, 0.5, 0.5, 82 | 0.5, 0.5, -0.5, 83 | 0.5, -0.5, -0.5, 84 | 0.5, -0.5, -0.5, 85 | 0.5, -0.5, 0.5, 86 | 0.5, 0.5, 0.5, 87 | 88 | -0.5, -0.5, -0.5, 89 | 0.5, -0.5, -0.5, 90 | 0.5, -0.5, 0.5, 91 | 0.5, -0.5, 0.5, 92 | -0.5, -0.5, 0.5, 93 | -0.5, -0.5, -0.5, 94 | 95 | -0.5, 0.5, -0.5, 96 | 0.5, 0.5, -0.5, 97 | 0.5, 0.5, 0.5, 98 | 0.5, 0.5, 0.5, 99 | -0.5, 0.5, 0.5, 100 | -0.5, 0.5, -0.5, 101 | ] 102 | vertices = (c_float * len(vertices))(*vertices) 103 | 104 | cube_vao = gl.glGenVertexArrays(1) 105 | vbo = gl.glGenBuffers(1) 106 | 107 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 108 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(vertices), vertices, gl.GL_STATIC_DRAW) 109 | 110 | gl.glBindVertexArray(cube_vao) 111 | 112 | # -- position attribute 113 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 114 | gl.glEnableVertexAttribArray(0) 115 | 116 | # -- second configure light vao (vbo is the same) 117 | light_vao = gl.glGenVertexArrays(1) 118 | gl.glBindVertexArray(light_vao) 119 | 120 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo) 121 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 3 * sizeof(c_float), c_void_p(0)) 122 | gl.glEnableVertexAttribArray(0) 123 | 124 | while not glfw.window_should_close(window): 125 | # -- time logic 126 | current_frame = glfw.get_time() 127 | delta_time = current_frame - last_frame 128 | last_frame = current_frame 129 | 130 | # -- input 131 | process_input(window) 132 | 133 | # -- render 134 | gl.glClearColor(0.1, 0.1, 0.1, 1.0) 135 | gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 136 | 137 | lighting_shader.use() 138 | lighting_shader.set_vec3("objectColor", Vector3([1.0, 0.5, 0.31])) 139 | lighting_shader.set_vec3("lightColor", Vector3([1.0, 1.0, 1.0])) 140 | 141 | # -- view.projection transformations 142 | projection = Matrix44.perspective_projection(camera.zoom, SRC_WIDTH/SRC_HEIGHT, 0.1, 100.0) 143 | view = camera.get_view_matrix() 144 | lighting_shader.set_mat4("projection", projection) 145 | lighting_shader.set_mat4("view", view) 146 | 147 | # -- world transformation 148 | model = Matrix44.identity() 149 | lighting_shader.set_mat4("model", model) 150 | 151 | # -- render cube 152 | gl.glBindVertexArray(cube_vao) 153 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) 154 | 155 | # -- draw lamp object 156 | lamp_shader.use() 157 | lamp_shader.set_mat4("projection", projection) 158 | lamp_shader.set_mat4("view", view) 159 | 160 | model = Matrix44.identity() 161 | model *= Matrix44.from_translation(light_pos) 162 | model *= Matrix44.from_scale(Vector3([.2, .2, .2])) 163 | lamp_shader.set_mat4("model", model) 164 | 165 | gl.glBindVertexArray(light_vao) 166 | gl.glDrawArrays(gl.GL_TRIANGLES, 0, 36) 167 | 168 | glfw.swap_buffers(window) 169 | glfw.poll_events() 170 | 171 | gl.glDeleteVertexArrays(1, id(cube_vao)) 172 | gl.glDeleteVertexArrays(1, id(light_vao)) 173 | gl.glDeleteBuffers(1, id(vbo)) 174 | glfw.terminate() 175 | 176 | 177 | def process_input(window): 178 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 179 | glfw.set_window_should_close(window, True) 180 | 181 | if glfw.get_key(window, glfw.KEY_W) == glfw.PRESS: 182 | camera.process_keyboard(CameraMovement.FORWARD, delta_time) 183 | if glfw.get_key(window, glfw.KEY_S) == glfw.PRESS: 184 | camera.process_keyboard(CameraMovement.BACKWARD, delta_time) 185 | 186 | if glfw.get_key(window, glfw.KEY_A) == glfw.PRESS: 187 | camera.process_keyboard(CameraMovement.LEFT, delta_time) 188 | if glfw.get_key(window, glfw.KEY_D) == glfw.PRESS: 189 | camera.process_keyboard(CameraMovement.RIGHT, delta_time) 190 | 191 | 192 | def framebuffer_size_callback(window, width, height): 193 | gl.glViewport(0, 0, width, height) 194 | 195 | 196 | def mouse_callback(window, xpos, ypos): 197 | global first_mouse, last_x, last_y 198 | 199 | if first_mouse: 200 | last_x, last_y = xpos, ypos 201 | first_mouse = False 202 | 203 | xoffset = xpos - last_x 204 | yoffset = last_y - ypos # XXX Note Reversed (y-coordinates go from bottom to top) 205 | last_x = xpos 206 | last_y = ypos 207 | 208 | camera.process_mouse_movement(xoffset, yoffset) 209 | 210 | 211 | def scroll_callback(window, xoffset, yoffset): 212 | camera.process_mouse_scroll(yoffset) 213 | 214 | 215 | if __name__ == '__main__': 216 | main() 217 | -------------------------------------------------------------------------------- /source/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 | FragColor = vec4(lightColor * objectColor, 1.0); 9 | } -------------------------------------------------------------------------------- /source/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 | gl_Position = projection * view * model * vec4(aPos, 1.0); 10 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/1.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | void main() { 5 | FragColor = vec4(1.0); 6 | } -------------------------------------------------------------------------------- /source/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 | gl_Position = projection * view * model * vec4(aPos, 1.0); 10 | } -------------------------------------------------------------------------------- /source/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 | } -------------------------------------------------------------------------------- /source/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 | FragPos = vec3(model * vec4(aPos, 1.0)); 14 | Normal = aNormal; 15 | 16 | gl_Position = projection * view * vec4(FragPos, 1.0); 17 | } -------------------------------------------------------------------------------- /source/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 viewPos; 8 | uniform vec3 lightPos; 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 | } -------------------------------------------------------------------------------- /source/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 | FragPos = vec3(model * vec4(aPos, 1.0)); 14 | Normal = mat3(transpose(inverse(model))) * aNormal; 15 | 16 | gl_Position = projection * view * vec4(FragPos, 1.0); 17 | } -------------------------------------------------------------------------------- /source/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 | 14 | vec3 ambient; 15 | vec3 diffuse; 16 | vec3 specular; 17 | }; 18 | 19 | in vec3 FragPos; 20 | in vec3 Normal; 21 | 22 | uniform vec3 viewPos; 23 | uniform Material material; 24 | uniform Light light; 25 | 26 | 27 | void main() { 28 | // ambient 29 | vec3 ambient = light.ambient * material.ambient; 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 * material.diffuse); 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 | } -------------------------------------------------------------------------------- /source/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 view; 9 | uniform mat4 model; 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 | } -------------------------------------------------------------------------------- /source/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 | 27 | void main() { 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 | } -------------------------------------------------------------------------------- /source/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 view; 11 | uniform mat4 model; 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 | } -------------------------------------------------------------------------------- /source/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 | 27 | void main() { 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 | } -------------------------------------------------------------------------------- /source/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 view; 11 | uniform mat4 model; 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 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/4.3.lighting_maps.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | struct Material { 6 | sampler2D diffuse; 7 | sampler2D specular; 8 | sampler2D emission; 9 | float shininess; 10 | 11 | }; 12 | 13 | struct Light { 14 | vec3 position; 15 | 16 | vec3 ambient; 17 | vec3 diffuse; 18 | vec3 specular; 19 | }; 20 | 21 | in vec3 FragPos; 22 | in vec3 Normal; 23 | in vec2 TexCoords; 24 | 25 | uniform vec3 viewPos; 26 | uniform Material material; 27 | uniform Light light; 28 | 29 | void main() { 30 | // ambient 31 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 32 | 33 | // diffuse 34 | vec3 norm = normalize(Normal); 35 | vec3 lightDir = normalize(light.position - FragPos); 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 | // emission 46 | vec3 emission = texture(material.emission, TexCoords).rgb; 47 | 48 | vec3 result = ambient + diffuse + specular + emission; 49 | FragColor = vec4(result, 1.0); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /source/2.lighting/shaders/4.3.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 view; 11 | uniform mat4 model; 12 | uniform mat4 projection; 13 | 14 | void main() { 15 | FragPos = vec3(model * vec4(aPos, 1.0)); 16 | Normal = mat3(transpose(inverse(model))) * aNormal; 17 | TexCoords = aTexCoords; 18 | 19 | gl_Position = projection * view * vec4(FragPos, 1.0); 20 | } 21 | -------------------------------------------------------------------------------- /source/2.lighting/shaders/5.1.light_casters.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | struct Material { 6 | sampler2D diffuse; 7 | sampler2D specular; 8 | float shininess; 9 | }; 10 | 11 | struct Light { 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.direction); 35 | float diff = max(dot(norm, lightDir), 0.0); 36 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 37 | 38 | // specular 39 | vec3 viewDir = normalize(viewPos - FragPos); 40 | vec3 reflectDir = reflect(-lightDir, norm); 41 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 42 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 43 | 44 | vec3 result = ambient + diffuse + specular; 45 | FragColor = vec4(result, 1.0); 46 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/5.1.light_casters.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec3 aNormal; 5 | layout (location = 2) in vec2 aTexCoords; 6 | 7 | out vec3 FragPos; 8 | out vec3 Normal; 9 | out vec2 TexCoords; 10 | 11 | uniform mat4 model; 12 | uniform mat4 view; 13 | uniform mat4 projection; 14 | 15 | void main() { 16 | 17 | FragPos = vec3(model * vec4(aPos, 1.0)); 18 | Normal = mat3(transpose(inverse(model))) * aNormal; 19 | TexCoords = aTexCoords; 20 | 21 | gl_Position = projection * view * vec4(FragPos, 1.0); 22 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/5.2.light_casters.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | struct Material { 6 | sampler2D diffuse; 7 | sampler2D specular; 8 | float shininess; 9 | }; 10 | 11 | struct Light { 12 | vec3 position; 13 | 14 | vec3 ambient; 15 | vec3 diffuse; 16 | vec3 specular; 17 | 18 | float constant; 19 | float linear; 20 | float quadratic; 21 | }; 22 | 23 | in vec3 FragPos; 24 | in vec3 Normal; 25 | in vec2 TexCoords; 26 | 27 | uniform vec3 viewPos; 28 | uniform Material material; 29 | uniform Light light; 30 | 31 | void main() { 32 | 33 | // ambient 34 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 35 | 36 | // diffuse 37 | vec3 norm = normalize(Normal); 38 | vec3 lightDir = normalize(light.position - FragPos); 39 | float diff = max(dot(norm, lightDir), 0.0); 40 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 41 | 42 | // specular 43 | vec3 viewDir = normalize(viewPos - FragPos); 44 | vec3 reflectDir = reflect(-lightDir, norm); 45 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 46 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 47 | 48 | // attenuation 49 | float distance = length(light.position - FragPos); 50 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 51 | 52 | ambient *= attenuation; 53 | diffuse *= attenuation; 54 | specular *= attenuation; 55 | 56 | vec3 result = ambient + diffuse + specular; 57 | FragColor = vec4(result, 1.0); 58 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/5.2.light_casters.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec3 aNormal; 5 | layout (location = 2) in vec2 aTexCoords; 6 | 7 | out vec3 FragPos; 8 | out vec3 Normal; 9 | out vec2 TexCoords; 10 | 11 | uniform mat4 model; 12 | uniform mat4 view; 13 | uniform mat4 projection; 14 | 15 | void main() { 16 | 17 | FragPos = vec3(model * vec4(aPos, 1.0)); 18 | Normal = mat3(transpose(inverse(model))) * aNormal; 19 | TexCoords = aTexCoords; 20 | 21 | gl_Position = projection * view * vec4(FragPos, 1.0); 22 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/5.3.light_casters.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | struct Material { 6 | sampler2D diffuse; 7 | sampler2D specular; 8 | float shininess; 9 | }; 10 | 11 | struct Light { 12 | vec3 position; 13 | vec3 direction; 14 | float cutOff; 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 | vec3 lightDir = normalize(light.position - FragPos); 35 | 36 | // check if lighting is inside the spotlight cone 37 | float theta = dot(lightDir, normalize(-light.direction)); 38 | 39 | // remember that we're working with angles as cosines instead of degrees so a '>' is used. 40 | if (theta > light.cutOff) { 41 | // ambient 42 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 43 | 44 | // diffuse 45 | vec3 norm = normalize(Normal); 46 | float diff = max(dot(norm, lightDir), 0.0); 47 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 48 | 49 | // specular 50 | vec3 viewDir = normalize(viewPos - FragPos); 51 | vec3 reflectDir = reflect(-lightDir, norm); 52 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 53 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 54 | 55 | // attenuation 56 | float distance = length(light.position - FragPos); 57 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 58 | 59 | // remove attenuation from ambient, as otherwise at large distances the light would be darker inside than outside 60 | // the spotlight due the ambient term in the else branch 61 | // ambient *= attenuation; 62 | diffuse *= attenuation; 63 | specular *= attenuation; 64 | 65 | vec3 result = ambient + diffuse + specular; 66 | FragColor = vec4(result, 1.0); 67 | } else { 68 | // else, use ambient light so scene isn't completely dark outside the spotlight. 69 | FragColor = vec4(light.ambient * texture(material.diffuse, TexCoords).rgb, 1.0); 70 | } 71 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/5.3.light_casters.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec3 aNormal; 5 | layout (location = 2) in vec2 aTexCoords; 6 | 7 | out vec3 FragPos; 8 | out vec3 Normal; 9 | out vec2 TexCoords; 10 | 11 | uniform mat4 model; 12 | uniform mat4 view; 13 | uniform mat4 projection; 14 | 15 | void main() { 16 | 17 | FragPos = vec3(model * vec4(aPos, 1.0)); 18 | Normal = mat3(transpose(inverse(model))) * aNormal; 19 | TexCoords = aTexCoords; 20 | 21 | gl_Position = projection * view * vec4(FragPos, 1.0); 22 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/5.4.light_casters.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | struct Material { 6 | sampler2D diffuse; 7 | sampler2D specular; 8 | float shininess; 9 | }; 10 | 11 | struct Light { 12 | vec3 position; 13 | vec3 direction; 14 | float cutOff; 15 | float outerCutOff; 16 | 17 | vec3 ambient; 18 | vec3 diffuse; 19 | vec3 specular; 20 | 21 | float constant; 22 | float linear; 23 | float quadratic; 24 | }; 25 | 26 | in vec3 FragPos; 27 | in vec3 Normal; 28 | in vec2 TexCoords; 29 | 30 | uniform vec3 viewPos; 31 | uniform Material material; 32 | uniform Light light; 33 | 34 | void main() { 35 | 36 | // ambient 37 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 38 | 39 | // diffuse 40 | vec3 norm = normalize(Normal); 41 | vec3 lightDir = normalize(light.position - FragPos); 42 | float diff = max(dot(norm, lightDir), 0.0); 43 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 44 | 45 | // specular 46 | vec3 viewDir = normalize(viewPos - FragPos); 47 | vec3 reflectDir = reflect(-lightDir, norm); 48 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 49 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 50 | 51 | // spotlight (soft edges) 52 | float theta = dot(lightDir, normalize(-light.direction)); 53 | float epsilon = (light.cutOff - light.outerCutOff); 54 | float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); 55 | diffuse *= intensity; 56 | specular *= intensity; 57 | 58 | 59 | // attenuation 60 | float distance = length(light.position - FragPos); 61 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 62 | ambient *= attenuation; 63 | diffuse *= attenuation; 64 | specular *= attenuation; 65 | 66 | vec3 result = ambient + diffuse + specular; 67 | FragColor = vec4(result, 1.0); 68 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/5.4.light_casters.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec3 aNormal; 5 | layout (location = 2) in vec2 aTexCoords; 6 | 7 | out vec3 FragPos; 8 | out vec3 Normal; 9 | out vec2 TexCoords; 10 | 11 | uniform mat4 model; 12 | uniform mat4 view; 13 | uniform mat4 projection; 14 | 15 | void main() { 16 | 17 | FragPos = vec3(model * vec4(aPos, 1.0)); 18 | Normal = mat3(transpose(inverse(model))) * aNormal; 19 | TexCoords = aTexCoords; 20 | 21 | gl_Position = projection * view * vec4(FragPos, 1.0); 22 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/6.1.lamp.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | out vec4 FragColor; 3 | 4 | uniform vec3 color; 5 | 6 | void main() { 7 | FragColor = vec4(color, 1.0); 8 | } -------------------------------------------------------------------------------- /source/2.lighting/shaders/6.multiple_lights.fs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | 5 | struct Material { 6 | sampler2D diffuse; 7 | sampler2D specular; 8 | float shininess; 9 | }; 10 | 11 | struct DirLight { 12 | vec3 direction; 13 | 14 | vec3 ambient; 15 | vec3 diffuse; 16 | vec3 specular; 17 | }; 18 | 19 | struct PointLight { 20 | vec3 position; 21 | 22 | float constant; 23 | float linear; 24 | float quadratic; 25 | 26 | vec3 ambient; 27 | vec3 diffuse; 28 | vec3 specular; 29 | }; 30 | 31 | struct SpotLight { 32 | vec3 position; 33 | vec3 direction; 34 | float cutOff; 35 | float outerCutOff; 36 | 37 | float constant; 38 | float linear; 39 | float quadratic; 40 | 41 | vec3 ambient; 42 | vec3 diffuse; 43 | vec3 specular; 44 | }; 45 | 46 | #define NR_POINT_LIGHTS 4 47 | 48 | 49 | in vec3 FragPos; 50 | in vec3 Normal; 51 | in vec2 TexCoords; 52 | 53 | uniform vec3 viewPos; 54 | uniform DirLight dirLight; 55 | uniform PointLight pointLights[NR_POINT_LIGHTS]; 56 | uniform SpotLight spotLight; 57 | uniform Material material; 58 | 59 | // function prototypes 60 | vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); 61 | vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragpos, vec3 viewDir); 62 | vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragpos, vec3 viewDir); 63 | 64 | void main() { 65 | // properties 66 | vec3 norm = normalize(Normal); 67 | vec3 viewDir = normalize(viewPos - FragPos); 68 | 69 | // == ===================================================== 70 | // Our lighting is set up in 3 phases: directional, point lights and an optional flashlight 71 | // For each phase, a calculate function is defined that calculates the corresponding color 72 | // per lamp. In the main() function we take all the calculated colors and sum them up for 73 | // this fragment's final color. 74 | // == ===================================================== 75 | // phase 1: directional lighting 76 | vec3 result = CalcDirLight(dirLight, norm, viewDir); 77 | // phase 2: point lightd 78 | for (int i = 0; i < NR_POINT_LIGHTS; i++) 79 | result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); 80 | // phase 3: spot light 81 | result += CalcSpotLight(spotLight, norm, FragPos, viewDir); 82 | 83 | FragColor = vec4(result, 1.0); 84 | } 85 | 86 | 87 | // calculates the color when using directional light 88 | vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir){ 89 | 90 | vec3 lightDir = normalize(-light.direction); 91 | // diffuse 92 | float diff = max(dot(normal, lightDir), 0.0); 93 | // specular 94 | vec3 reflectDir = reflect(-lightDir, normal); 95 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 96 | // combine results 97 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 98 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 99 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 100 | return (ambient + diffuse + specular); 101 | } 102 | 103 | // calculates the color when using point light 104 | vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragpos, vec3 viewDir){ 105 | vec3 lightDir = normalize(light.position - fragpos); 106 | // diffuse 107 | float diff = max(dot(normal, lightDir), 0.0); 108 | // specular 109 | vec3 reflectDir = reflect(-lightDir, normal); 110 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 111 | // attenuation 112 | float distance = length(light.position - FragPos); 113 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 114 | // combine results 115 | vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb; 116 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 117 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 118 | ambient *= attenuation; 119 | diffuse *= attenuation; 120 | specular *= attenuation; 121 | return (ambient + diffuse + specular); 122 | } 123 | 124 | // calculates the color when using spot light 125 | vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragpos, vec3 viewDir){ 126 | vec3 lightDir = normalize(light.position - fragpos); 127 | // diffuse 128 | float diff = max(dot(normal, lightDir), 0.0); 129 | // specular 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 * texture(material.diffuse, TexCoords).rgb; 141 | vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb; 142 | vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb; 143 | ambient *= attenuation * intensity; 144 | diffuse *= attenuation * intensity; 145 | specular *= attenuation * intensity; 146 | return (ambient + diffuse + specular); 147 | } 148 | -------------------------------------------------------------------------------- /source/2.lighting/shaders/6.multiple_lights.vs: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec3 aNormal; 5 | layout (location = 2) in vec2 aTexCoords; 6 | 7 | out vec3 FragPos; 8 | out vec3 Normal; 9 | out vec2 TexCoords; 10 | 11 | uniform mat4 model; 12 | uniform mat4 view; 13 | uniform mat4 projection; 14 | 15 | void main() { 16 | 17 | FragPos = vec3(model * vec4(aPos, 1.0)); 18 | Normal = mat3(transpose(inverse(model))) * aNormal; 19 | TexCoords = aTexCoords; 20 | 21 | gl_Position = projection * view * vec4(FragPos, 1.0); 22 | } -------------------------------------------------------------------------------- /source/3.model_loading/1.model_loading.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import glfw 3 | import OpenGL.GL as gl 4 | from pathlib import Path 5 | from pyrr import Vector3, Matrix44 6 | 7 | CURDIR = Path(__file__).absolute().parent 8 | RESDIR = CURDIR.parent.parent.joinpath("resources") 9 | 10 | sys.path.append(str(CURDIR.parent)) 11 | from model import Model 12 | from shader import Shader 13 | from camera import Camera, CameraMovement 14 | 15 | # -- settings 16 | SRC_WIDTH = 800 17 | SRC_HEIGHT = 600 18 | 19 | # -- camera 20 | camera = Camera(Vector3([0.0, 0.0, 3.0])) 21 | last_x = SRC_WIDTH / 2 22 | last_y = SRC_HEIGHT / 2 23 | first_mouse = True 24 | 25 | # -- timing 26 | delta_time = 0.0 27 | last_frame = 0.0 28 | 29 | 30 | def main(): 31 | global delta_time, last_frame 32 | 33 | if not glfw.init(): 34 | raise ValueError("Failed to initialize glfw") 35 | 36 | glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) 37 | glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) 38 | glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) 39 | 40 | window = glfw.create_window(SRC_WIDTH, SRC_HEIGHT, "learnOpenGL", None, None) 41 | if not window: 42 | glfw.terminate() 43 | raise ValueError("Failed to create window") 44 | 45 | glfw.make_context_current(window) 46 | glfw.set_framebuffer_size_callback(window, framebuffer_size_callback) 47 | glfw.set_cursor_pos_callback(window, mouse_callback) 48 | glfw.set_scroll_callback(window, scroll_callback) 49 | 50 | glfw.set_input_mode(window, glfw.CURSOR, glfw.CURSOR_DISABLED) 51 | 52 | gl.glEnable(gl.GL_DEPTH_TEST) 53 | 54 | model = Model(str(RESDIR.joinpath("objects/nanosuit/nanosuit.obj"))) 55 | model_shader = Shader(str(CURDIR / "shaders/model_loading.vs"), str(CURDIR / "shaders/model_loading.fs")) 56 | # draw in wireframe 57 | # gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE) 58 | # sys.exit() 59 | 60 | while not glfw.window_should_close(window): 61 | # -- time logic 62 | current_frame = glfw.get_time() 63 | delta_time = current_frame - last_frame 64 | last_frame = current_frame 65 | 66 | # -- input 67 | process_input(window) 68 | 69 | # -- render 70 | gl.glClearColor(0.05, 0.05, 0.05, 1.0) 71 | gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) 72 | 73 | model_shader.use() 74 | 75 | # -- view.projection transformations 76 | view = camera.get_view_matrix() 77 | projection = Matrix44.perspective_projection( 78 | camera.zoom, SRC_WIDTH/SRC_HEIGHT, 0.1, 100.0 79 | ) 80 | model_shader.set_mat4("projection", projection) 81 | model_shader.set_mat4("view", view) 82 | 83 | # -- world transformation 84 | modelm = Matrix44.identity() 85 | modelm *= Matrix44.from_translation([0.0, -0.75, 0.0]) 86 | modelm *= Matrix44.from_scale([0.2, 0.2, 0.2]) 87 | model_shader.set_mat4("model", modelm) 88 | 89 | model.draw(model_shader) 90 | 91 | glfw.swap_buffers(window) 92 | glfw.poll_events() 93 | 94 | glfw.terminate() 95 | 96 | 97 | def process_input(window): 98 | if glfw.get_key(window, glfw.KEY_ESCAPE) == glfw.PRESS: 99 | glfw.set_window_should_close(window, True) 100 | 101 | if glfw.get_key(window, glfw.KEY_W) == glfw.PRESS: 102 | camera.process_keyboard(CameraMovement.FORWARD, delta_time) 103 | if glfw.get_key(window, glfw.KEY_S) == glfw.PRESS: 104 | camera.process_keyboard(CameraMovement.BACKWARD, delta_time) 105 | 106 | if glfw.get_key(window, glfw.KEY_A) == glfw.PRESS: 107 | camera.process_keyboard(CameraMovement.LEFT, delta_time) 108 | if glfw.get_key(window, glfw.KEY_D) == glfw.PRESS: 109 | camera.process_keyboard(CameraMovement.RIGHT, delta_time) 110 | 111 | 112 | def framebuffer_size_callback(window, width, height): 113 | gl.glViewport(0, 0, width, height) 114 | 115 | 116 | def mouse_callback(window, xpos, ypos): 117 | global first_mouse, last_x, last_y 118 | 119 | if first_mouse: 120 | last_x, last_y = xpos, ypos 121 | first_mouse = False 122 | 123 | xoffset = xpos - last_x 124 | yoffset = last_y - ypos # XXX Note Reversed (y-coordinates go from bottom to top) 125 | last_x = xpos 126 | last_y = ypos 127 | 128 | camera.process_mouse_movement(xoffset, yoffset) 129 | 130 | 131 | def scroll_callback(window, xoffset, yoffset): 132 | camera.process_mouse_scroll(yoffset) 133 | 134 | 135 | if __name__ == '__main__': 136 | main() 137 | -------------------------------------------------------------------------------- /source/3.model_loading/shaders/model_loading.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 | FragColor = texture(texture_diffuse1, TexCoords); 10 | } 11 | -------------------------------------------------------------------------------- /source/3.model_loading/shaders/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 | TexCoords = aTexCoords; 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } -------------------------------------------------------------------------------- /source/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 | } -------------------------------------------------------------------------------- /source/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 | } -------------------------------------------------------------------------------- /source/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ranjian0/learnopengl-python/8edd4e2612d90f64f2b514008872b2d061b29bbf/source/__init__.py -------------------------------------------------------------------------------- /source/camera.py: -------------------------------------------------------------------------------- 1 | import math 2 | from pyrr import Vector3, Matrix44 3 | from enum import Enum, auto 4 | 5 | 6 | YAW = -90.0 7 | ZOOM = 45.0 8 | SPEED = 2.5 9 | PITCH = 0.0 10 | SENSITIVITY = 0.1 11 | 12 | 13 | class CameraMovement(Enum): 14 | LEFT = auto() 15 | RIGHT = auto() 16 | FORWARD = auto() 17 | BACKWARD = auto() 18 | 19 | 20 | class Camera: 21 | 22 | def __init__(self, position=Vector3(), up=Vector3([0, 1, 0]), yaw=YAW, pitch=PITCH): 23 | self.position = position 24 | self.front = Vector3([0.0, 0.0, -1.0]) 25 | self.world_up = up 26 | 27 | self.yaw = yaw 28 | self.pitch = pitch 29 | 30 | self.zoom = ZOOM 31 | self.movement_speed = SPEED 32 | self.mouse_sensitivity = SENSITIVITY 33 | 34 | self.update_camera_vectors() 35 | 36 | def get_view_matrix(self): 37 | return Matrix44.look_at(self.position, self.position + self.front, self.up) 38 | 39 | def process_keyboard(self, direction, delta_time): 40 | velocity = self.movement_speed * delta_time 41 | 42 | dir_vector = { 43 | CameraMovement.LEFT : -self.right * velocity, 44 | CameraMovement.RIGHT : self.right * velocity, 45 | CameraMovement.FORWARD : self.front * velocity, 46 | CameraMovement.BACKWARD : -self.front * velocity, 47 | }.get(direction) 48 | self.position += dir_vector 49 | 50 | def process_mouse_movement(self, xoffset, yoffset, constrain_pitch=True): 51 | xoffset *= self.mouse_sensitivity 52 | yoffset *= self.mouse_sensitivity 53 | 54 | self.yaw += xoffset 55 | self.pitch += yoffset 56 | 57 | if constrain_pitch: 58 | self.pitch = max(-89.0, min(89.0, self.pitch)) 59 | 60 | self.update_camera_vectors() 61 | 62 | def process_mouse_scroll(self, yoffset): 63 | if self.zoom >= 1.0 and self.zoom <= 45.0: 64 | self.zoom -= yoffset 65 | 66 | self.zoom = max(1.0, min(45.0, self.zoom)) 67 | 68 | def update_camera_vectors(self): 69 | # -- calc front vector 70 | front = Vector3() 71 | front.x = math.cos(math.radians(self.yaw)) * math.cos(math.radians(self.pitch)) 72 | front.y = math.sin(math.radians(self.pitch)) 73 | front.z = math.sin(math.radians(self.yaw)) * math.cos(math.radians(self.pitch)) 74 | self.front = front.normalized 75 | 76 | # -- recalc right and up 77 | self.right = self.front.cross(self.world_up).normalized 78 | self.up = self.right.cross(self.front).normalized 79 | -------------------------------------------------------------------------------- /source/mesh.py: -------------------------------------------------------------------------------- 1 | import OpenGL.GL as gl 2 | from ctypes import c_float, sizeof, c_void_p, Structure 3 | 4 | 5 | Vec2 = (2 * c_float) 6 | Vec3 = (3 * c_float) 7 | 8 | class Vertex(Structure): 9 | _fields_ = [ 10 | ("Position", Vec3), 11 | ("Normal", Vec3), 12 | ("TexCoords", Vec2), 13 | ("Tangent", Vec3), 14 | ("Bitangent", Vec3), 15 | ] 16 | 17 | 18 | class Texture: 19 | def __init__(self, id=0, type="", path=""): 20 | self.id = id 21 | self.type = type 22 | self.path = path 23 | 24 | def __repr__(self): 25 | return "Texture".format(self.id, self.path) 26 | 27 | 28 | class Mesh: 29 | def __init__(self, data, indices, textures=None): 30 | self.data = data 31 | self.indices = indices 32 | self.textures = textures 33 | 34 | self.vao = None 35 | 36 | self._vbo = None 37 | self._ebo = None 38 | self._setup_mesh() 39 | 40 | def draw(self, shader): 41 | normal_nr = 1 42 | height_nr = 1 43 | diffuse_nr = 1 44 | specular_nr = 1 45 | 46 | for idx, texture in enumerate(self.textures): 47 | gl.glActiveTexture(gl.GL_TEXTURE0 + idx) 48 | 49 | number = str() 50 | name = texture.type 51 | if name == 'texture_diffuse': 52 | number = str(diffuse_nr) 53 | diffuse_nr += 1 54 | elif name == 'texture_specular': 55 | number = str(specular_nr) 56 | specular_nr += 1 57 | elif name == 'texture_normal': 58 | number = str(normal_nr) 59 | normal_nr += 1 60 | elif name == 'texture_height': 61 | number = str(height_nr) 62 | height_nr += 1 63 | 64 | shader.set_int(name + number, idx) 65 | gl.glBindTexture(gl.GL_TEXTURE_2D, texture.id) 66 | 67 | gl.glBindVertexArray(self.vao) 68 | gl.glDrawElements(gl.GL_TRIANGLES, len(self.indices), gl.GL_UNSIGNED_INT, c_void_p(0)) 69 | gl.glBindVertexArray(0) 70 | gl.glActiveTexture(gl.GL_TEXTURE0) 71 | 72 | def _setup_mesh(self): 73 | self.vao = gl.glGenVertexArrays(1) 74 | gl.glBindVertexArray(self.vao) 75 | 76 | self._vbo = gl.glGenBuffers(1) 77 | gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo) 78 | gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(self.data), self.data, gl.GL_STATIC_DRAW) 79 | 80 | self._ebo = gl.glGenBuffers(1) 81 | gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._ebo) 82 | gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, sizeof(self.indices), self.indices, gl.GL_STATIC_DRAW) 83 | 84 | # -- set vertex attibute pointers 85 | # -- vertex positions 86 | gl.glEnableVertexAttribArray(0) 87 | gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 88 | sizeof(Vertex), c_void_p(Vertex.Position.offset)) 89 | 90 | # -- vertex normals 91 | gl.glEnableVertexAttribArray(1) 92 | gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 93 | sizeof(Vertex), c_void_p(Vertex.Normal.offset)) 94 | 95 | # -- vertex texture coords 96 | gl.glEnableVertexAttribArray(2) 97 | gl.glVertexAttribPointer(2, 2, gl.GL_FLOAT, gl.GL_FALSE, 98 | sizeof(Vertex), c_void_p(Vertex.TexCoords.offset)) 99 | 100 | # -- vertex tangent 101 | gl.glEnableVertexAttribArray(3) 102 | gl.glVertexAttribPointer(3, 3, gl.GL_FLOAT, gl.GL_FALSE, 103 | sizeof(Vertex), c_void_p(Vertex.Tangent.offset)) 104 | 105 | # -- vertex bitangent 106 | gl.glEnableVertexAttribArray(4) 107 | gl.glVertexAttribPointer(4, 3, gl.GL_FLOAT, gl.GL_FALSE, 108 | sizeof(Vertex), c_void_p(Vertex.Bitangent.offset)) 109 | 110 | 111 | gl.glBindVertexArray(0) 112 | -------------------------------------------------------------------------------- /source/model.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import ctypes 4 | import OpenGL.GL as gl 5 | import assimp_py as assimp 6 | 7 | from PIL import Image 8 | from mesh import Texture, Mesh, Vertex, Vec2, Vec3 9 | 10 | 11 | class Model: 12 | 13 | def __init__(self, path, gamma=False): 14 | self.path = path 15 | self.textures_loaded = set() 16 | self.meshes = list() 17 | self.directory = "" 18 | self.gamma_correction = gamma 19 | 20 | self._load_model() 21 | 22 | def draw(self, shader): 23 | for mesh in self.meshes: 24 | mesh.draw(shader) 25 | 26 | def _load_model(self): 27 | path = self.path 28 | start_time = time.time() 29 | 30 | post_process = (assimp.Process_Triangulate | 31 | assimp.Process_FlipUVs | 32 | assimp.Process_CalcTangentSpace) 33 | scene = assimp.ImportFile(path, post_process) 34 | if not scene: 35 | raise ValueError("ERROR:: Assimp model failed to load, {}".format(path)) 36 | 37 | self.directory = os.path.dirname(path) 38 | for m in scene.meshes: 39 | self.meshes.append(self._process_mesh(m, scene)) 40 | 41 | print("Took {}s to load model {}".format( 42 | round(time.time()-start_time, 3), os.path.basename(path))) 43 | 44 | def _process_mesh(self, mesh, scene): 45 | vertices = (mesh.num_vertices * Vertex)() 46 | for i in range(mesh.num_vertices): 47 | vertices[i].Position = Vec3(*mesh.vertices[i]) 48 | vertices[i].Normal = Vec3(*mesh.normals[i]) 49 | if mesh.texcoords[0]: 50 | vertices[i].TexCoords = Vec2(*mesh.texcoords[0][i][:2]) 51 | vertices[i].Tangent = Vec3(*mesh.tangents[i]) 52 | vertices[i].Bitangent = Vec3(*mesh.bitangents[i]) 53 | else: 54 | vertices[i].TexCoords = Vec2(0, 0) 55 | vertices[i].Tangent = Vec3(0, 0, 0) 56 | vertices[i].Bitangent = Vec3(0, 0, 0) 57 | 58 | idx = [i for face in mesh.indices for i in face] 59 | indices = (ctypes.c_uint * len(idx))(*idx) 60 | 61 | # process materials 62 | textures = [] 63 | material = scene.materials[mesh.material_index] 64 | 65 | # we assume a convention for sampler names in the shaders. Each diffuse texture should be named 66 | # as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER. 67 | # Same applies to other texture as the following list summarizes: 68 | # diffuse: texture_diffuseN 69 | # specular: texture_specularN 70 | # normal: texture_normalN 71 | 72 | # 1. diffuse maps 73 | diffuse_maps = self._load_material_textures( 74 | material, assimp.TextureType_DIFFUSE, "texture_diffuse") 75 | textures.extend(diffuse_maps) 76 | 77 | # 2. specular maps 78 | specular_maps = self._load_material_textures( 79 | material, assimp.TextureType_SPECULAR, "texture_specular") 80 | textures.extend(specular_maps) 81 | 82 | # 3. normal maps 83 | normal_maps = self._load_material_textures( 84 | material, assimp.TextureType_HEIGHT, "texture_normal") 85 | textures.extend(normal_maps) 86 | 87 | # 4. height maps 88 | height_maps = self._load_material_textures( 89 | material, assimp.TextureType_AMBIENT, "texture_height") 90 | textures.extend(height_maps) 91 | 92 | return Mesh(vertices, indices, textures) 93 | 94 | def _load_material_textures(self, mat, type, type_name): 95 | textures = [] 96 | 97 | paths = mat["TEXTURES"].get(type) 98 | if paths: 99 | for p in paths: 100 | 101 | skip = False 102 | for tex in self.textures_loaded: 103 | if p == tex.path: 104 | textures.append(tex) 105 | skip = True 106 | break 107 | 108 | if not skip: 109 | tex = Texture(TextureFromFile(p, self.directory), type_name, p) 110 | textures.append(tex) 111 | self.textures_loaded.add(tex) 112 | 113 | return textures 114 | 115 | 116 | def TextureFromFile(path, directory, gamma=False): 117 | textureID = gl.glGenTextures(1) 118 | img = Image.open(os.path.join(directory, path)) 119 | 120 | format_ = { 121 | 1 : gl.GL_RED, 122 | 3 : gl.GL_RGB, 123 | 4 : gl.GL_RGBA, 124 | }.get(len(img.getbands())) 125 | 126 | gl.glBindTexture(gl.GL_TEXTURE_2D, textureID) 127 | gl.glTexImage2D( 128 | gl.GL_TEXTURE_2D, 0, format_, img.width, img.height, 129 | 0, format_, gl.GL_UNSIGNED_BYTE, img.tobytes() 130 | ) 131 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 132 | 133 | # -- texture wrapping 134 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) 135 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) 136 | # -- texture filterting 137 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR_MIPMAP_LINEAR) 138 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) 139 | 140 | return textureID 141 | -------------------------------------------------------------------------------- /source/shader.py: -------------------------------------------------------------------------------- 1 | import OpenGL.GL as gl 2 | from OpenGL.GL import shaders 3 | 4 | 5 | class Shader: 6 | 7 | def __init__(self, vertex_path, fragment_path, geometry_path=None): 8 | self.ID = shaders.compileProgram( 9 | shaders.compileShader(self._load(vertex_path), gl.GL_VERTEX_SHADER), 10 | shaders.compileShader(self._load(fragment_path), gl.GL_FRAGMENT_SHADER), 11 | ) 12 | 13 | def _load(self, path): 14 | shader_source = "" 15 | with open(path, 'r') as shader_file: 16 | shader_source = shader_file.readlines() 17 | return shader_source 18 | 19 | def use(self): 20 | gl.glUseProgram(self.ID) 21 | 22 | def set_bool(self, name, value): 23 | gl.glUniform1i(gl.glGetUniformLocation(self.ID, name), value) 24 | 25 | def set_int(self, name, value): 26 | gl.glUniform1i(gl.glGetUniformLocation(self.ID, name), value) 27 | 28 | def set_float(self, name, value): 29 | gl.glUniform1f(gl.glGetUniformLocation(self.ID, name), value) 30 | 31 | def set_vec2(self, name, value): 32 | gl.glUniform2fv(gl.glGetUniformLocation(self.ID, name), 1, value) 33 | 34 | def set_vec3(self, name, value): 35 | gl.glUniform3fv(gl.glGetUniformLocation(self.ID, name), 1, value) 36 | 37 | def set_vec4(self, name, value): 38 | gl.glUniform4fv(gl.glGetUniformLocation(self.ID, name), 1, value) 39 | 40 | def set_mat3(self, name, value): 41 | gl.glUniformMatrix3fv(gl.glGetUniformLocation(self.ID, name), 1, gl.GL_FALSE, value) 42 | 43 | def set_mat4(self, name, value): 44 | gl.glUniformMatrix4fv(gl.glGetUniformLocation(self.ID, name), 1, gl.GL_FALSE, value) 45 | -------------------------------------------------------------------------------- /source/texture.py: -------------------------------------------------------------------------------- 1 | import os 2 | import OpenGL.GL as gl 3 | 4 | from PIL import Image 5 | from pathlib import Path 6 | 7 | 8 | RESOURCES = Path(__file__).absolute().parent.parent.joinpath('resources') 9 | TEXTURES_DIR = RESOURCES.joinpath('textures') 10 | 11 | 12 | def load_texture(path, 13 | mag_filter=gl.GL_LINEAR, 14 | min_filter=gl.GL_LINEAR_MIPMAP_LINEAR, 15 | wrap_s=gl.GL_REPEAT, wrap_t=gl.GL_REPEAT, 16 | flip_y=False, flip_x=False, 17 | generate_mipmaps=True): 18 | 19 | textureID = gl.glGenTextures(1) 20 | img = Image.open(os.path.join(TEXTURES_DIR, path)) 21 | img = flip_image(img, flip_x, flip_y) 22 | 23 | format_ = { 24 | 1 : gl.GL_RED, 25 | 3 : gl.GL_RGB, 26 | 4 : gl.GL_RGBA, 27 | }.get(len(img.getbands())) 28 | 29 | gl.glBindTexture(gl.GL_TEXTURE_2D, textureID) 30 | gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, format_, img.width, img.height, 0, format_, gl.GL_UNSIGNED_BYTE, img.tobytes()) 31 | if generate_mipmaps: 32 | gl.glGenerateMipmap(gl.GL_TEXTURE_2D) 33 | 34 | # -- texture wrapping 35 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, wrap_s) 36 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, wrap_t) 37 | # -- texture filterting 38 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, min_filter) 39 | gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, mag_filter) 40 | 41 | return textureID 42 | 43 | 44 | def flip_image(img, flip_y=False, flip_x=False): 45 | if flip_y: 46 | return img.transpose(Image.FLIP_TOP_BOTTOM) 47 | elif flip_x: 48 | return img.transpose(Image.FLIP_LEFT_RIGHT) 49 | return img 50 | --------------------------------------------------------------------------------