├── .gitignore ├── CMakeLists.txt ├── README.md ├── fips ├── fips-files ├── configs │ ├── webgl2-wasm-ninja-debug.yml │ └── webgl2-wasm-ninja-release.yml └── verbs │ └── webpage.py ├── fips.cmd ├── fips.yml ├── libs ├── CMakeLists.txt ├── cgltf │ └── readme.txt ├── fast_obj │ ├── fast_obj.h │ ├── lopgl_fast_obj.h │ └── readme.txt ├── hmm │ ├── HandmadeMath.h │ └── readme.txt ├── sokol │ ├── CMakeLists.txt │ ├── sokol.c │ └── sokol.m └── stb │ ├── readme.txt │ └── stb_image.h ├── src ├── 1-3-hello-window │ ├── 1-rendering.c │ └── CMakeLists.txt ├── 1-4-hello-triangle │ ├── 1-triangle.c │ ├── 1-triangle.glsl │ ├── 2-quad.c │ ├── 2-quad.glsl │ ├── 3-quad-wireframe.c │ ├── 3-quad-wireframe.glsl │ └── CMakeLists.txt ├── 1-5-shaders │ ├── 1-in-out.c │ ├── 1-in-out.glsl │ ├── 2-uniforms.c │ ├── 2-uniforms.glsl │ ├── 3-attributes.c │ ├── 3-attributes.glsl │ └── CMakeLists.txt ├── 1-6-textures │ ├── 1-texture.c │ ├── 1-texture.glsl │ ├── 2-texture-blend.c │ ├── 2-texture-blend.glsl │ ├── 3-multiple-textures.c │ ├── 3-multiple-textures.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 1-7-transformations │ ├── 1-scale-rotate.c │ ├── 2-rotate-translate.c │ ├── CMakeLists.txt │ ├── textures-assets.yml │ └── transformations.glsl ├── 1-8-coordinate-systems │ ├── 1-plane.c │ ├── 2-cube.c │ ├── 3-more-cubes.c │ ├── CMakeLists.txt │ ├── shaders.glsl │ └── textures-assets.yml ├── 1-9-camera │ ├── 1-lookat.c │ ├── 2-walk.c │ ├── 3-look.c │ ├── CMakeLists.txt │ ├── shaders.glsl │ └── textures-assets.yml ├── 2-1-colors │ ├── 1-scene.c │ ├── CMakeLists.txt │ └── shaders.glsl ├── 2-2-basic-lighting │ ├── 1-ambient.c │ ├── 1-ambient.glsl │ ├── 2-diffuse.c │ ├── 2-diffuse.glsl │ ├── 3-specular.c │ ├── 3-specular.glsl │ └── CMakeLists.txt ├── 2-3-materials │ ├── 1-material.c │ ├── 1-material.glsl │ ├── 2-light.c │ ├── 2-light.glsl │ ├── 3-light-colors.c │ ├── 3-light-colors.glsl │ └── CMakeLists.txt ├── 2-4-lighting-maps │ ├── 1-diffuse-map.c │ ├── 1-diffuse-map.glsl │ ├── 2-specular-map.c │ ├── 2-specular-map.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 2-5-light-casters │ ├── 1-directional-light.c │ ├── 1-directional-light.glsl │ ├── 2-point-light.c │ ├── 2-point-light.glsl │ ├── 3-spot-light.c │ ├── 3-spot-light.glsl │ ├── 4-soft-spot-light.c │ ├── 4-soft-spot-light.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 2-6-multiple-lights │ ├── 1-combined-lights.c │ ├── 1-combined-lights.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 3-1-model │ ├── 1-backpack-diffuse.c │ ├── 1-backpack-diffuse.glsl │ ├── 2-backpack-lights.c │ ├── 2-backpack-lights.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 4-1-depth-testing │ ├── 1-depth-always.c │ ├── 1-depth-always.glsl │ ├── 2-depth-less.c │ ├── 2-depth-less.glsl │ ├── 3-depth-buffer.c │ ├── 3-depth-buffer.glsl │ ├── 4-linear-depth-buffer.c │ ├── 4-linear-depth-buffer.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 4-10-instancing │ ├── 1-instancing.c │ ├── 1-instancing.glsl │ ├── 2-instanced-arrays.c │ ├── 2-instanced-arrays.glsl │ ├── 3-asteroid-field.c │ ├── 3-asteroid-field.glsl │ ├── 4-asteroid-field-instanced.c │ ├── 4-asteroid-field-instanced.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 4-11-anti-aliasing │ ├── 1-msaa.c │ ├── 1-msaa.glsl │ ├── 2-offscreen-msaa.c │ ├── 2-offscreen-msaa.glsl │ ├── 3-grayscale-msaa.c │ ├── 3-grayscale-msaa.glsl │ └── CMakeLists.txt ├── 4-2-stencil-testing │ ├── 1-object-outlining.c │ ├── 1-object-outlining.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 4-3-blending │ ├── 1-grass-opaque.c │ ├── 1-grass-opaque.glsl │ ├── 2-grass-transparent.c │ ├── 2-grass-transparent.glsl │ ├── 3-blending.c │ ├── 3-blending.glsl │ ├── 4-blending-sorted.c │ ├── 4-blending-sorted.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 4-4-face-culling │ ├── 1-cull-front.c │ ├── 1-cull-front.glsl │ └── CMakeLists.txt ├── 4-5-framebuffers │ ├── 1-render-to-texture.c │ ├── 1-render-to-texture.glsl │ ├── 2-inversion.c │ ├── 2-inversion.glsl │ ├── 3-grayscale.c │ ├── 3-grayscale.glsl │ ├── 4-sharpen.c │ ├── 4-sharpen.glsl │ ├── 5-blur.c │ ├── 5-blur.glsl │ ├── 6-edge-detection.c │ ├── 6-edge-detection.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 4-6-cubemaps │ ├── 1-skybox.c │ ├── 1-skybox.glsl │ ├── 2-reflection-cube.c │ ├── 2-reflection-cube.glsl │ ├── 3-reflection-backpack.c │ ├── 3-reflection-backpack.glsl │ ├── 4-refraction-cube.c │ ├── 4-refraction-cube.glsl │ ├── 5-refraction-backpack.c │ ├── 5-refraction-backpack.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 4-8-advanced-glsl │ ├── 1-point-size.c │ ├── 1-point-size.glsl │ ├── 2-frag-coord.c │ ├── 2-frag-coord.glsl │ ├── 3-front-facing.c │ ├── 3-front-facing.glsl │ ├── 4-uniform-buffers.c │ ├── 4-uniform-buffers.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 4-9-geometry-shader │ ├── 1-lines.c │ ├── 1-lines.glsl │ ├── 2-houses.c │ ├── 2-houses.glsl │ ├── 3-exploding-object.c │ ├── 3-exploding-object.glsl │ ├── 4-visualizing-normals.c │ ├── 4-visualizing-normals.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 5-1-advanced-lighting │ ├── 1-blinn-phong.c │ ├── 1-blinn-phong.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 5-2-gamma-correction │ ├── 1-gamma-correction.c │ ├── 1-gamma-correction.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 5-3-shadow-mapping │ ├── 1-mapping-depth.c │ ├── 1-mapping-depth.glsl │ ├── 2-rendering-shadows.c │ ├── 2-rendering-shadows.glsl │ ├── 3-improved-shadows.c │ ├── 3-improved-shadows.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 5-4-point-shadows │ ├── 1-omnidirectional-depth.c │ ├── 1-omnidirectional-depth.glsl │ ├── 2-omnidirectional-shadows.c │ ├── 2-omnidirectional-shadows.glsl │ ├── 3-omnidirectional-PCF.c │ ├── 3-omnidirectional-PCF.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── 5-5-normal-mapping │ ├── 1-normal-mapping.c │ ├── 1-normal-mapping.glsl │ ├── 2-tangent-space.c │ ├── 2-tangent-space.glsl │ ├── 3-complex-object.c │ ├── 3-complex-object.glsl │ ├── CMakeLists.txt │ └── textures-assets.yml ├── CMakeLists.txt ├── data │ ├── awesomeface.png │ ├── backpack.mtl │ ├── backpack.obj │ ├── backpack_diffuse.jpg │ ├── backpack_normal.png │ ├── backpack_specular.jpg │ ├── brickwall.jpg │ ├── brickwall_normal.jpg │ ├── container.jpg │ ├── container2.png │ ├── container2_specular.png │ ├── grass.png │ ├── marble.jpg │ ├── mars.png │ ├── metal.png │ ├── planet.mtl │ ├── planet.obj │ ├── rock.mtl │ ├── rock.obj │ ├── rock.png │ ├── skybox_back.jpg │ ├── skybox_bottom.jpg │ ├── skybox_front.jpg │ ├── skybox_left.jpg │ ├── skybox_right.jpg │ ├── skybox_top.jpg │ ├── transparent_window.png │ ├── uv_grid.png │ └── wood.png └── lopgl_app.h └── webpage ├── 1-3-1-rendering.jpg ├── 1-4-1-triangle.jpg ├── 1-4-2-quad.jpg ├── 1-4-3-quad-wireframe.jpg ├── 1-5-1-in-out.jpg ├── 1-5-2-uniforms.jpg ├── 1-5-3-attributes.jpg ├── 1-6-1-texture.jpg ├── 1-6-2-texture-blend.jpg ├── 1-6-3-multiple-textures.jpg ├── 1-7-1-scale-rotate.jpg ├── 1-7-2-rotate-translate.jpg ├── 1-8-1-plane.jpg ├── 1-8-2-cube.jpg ├── 1-8-3-more-cubes.jpg ├── 1-9-1-lookat.jpg ├── 1-9-2-walk.jpg ├── 1-9-3-look.jpg ├── 2-1-1-scene.jpg ├── 2-2-1-ambient.jpg ├── 2-2-2-diffuse.jpg ├── 2-2-3-specular.jpg ├── 2-3-1-material.jpg ├── 2-3-2-light.jpg ├── 2-3-3-light-colors.jpg ├── 2-4-1-diffuse-map.jpg ├── 2-4-2-specular-map.jpg ├── 2-5-1-directional-light.jpg ├── 2-5-2-point-light.jpg ├── 2-5-3-spot-light.jpg ├── 2-5-4-soft-spot-light.jpg ├── 2-6-1-combined-lights.jpg ├── 3-1-1-backpack-diffuse.jpg ├── 3-1-2-backpack-lights.jpg ├── 4-1-1-depth-always.jpg ├── 4-1-2-depth-less.jpg ├── 4-1-3-depth-buffer.jpg ├── 4-1-4-linear-depth-buffer.jpg ├── 4-10-1-instancing.jpg ├── 4-10-2-instanced-arrays.jpg ├── 4-10-3-asteroid-field.jpg ├── 4-10-4-asteroid-field-instanced.jpg ├── 4-11-1-msaa.jpg ├── 4-11-2-offscreen-msaa.jpg ├── 4-11-3-grayscale-msaa.jpg ├── 4-2-1-object-outlining.jpg ├── 4-3-1-grass-opaque.jpg ├── 4-3-2-grass-transparent.jpg ├── 4-3-3-blending.jpg ├── 4-3-4-blending-sorted.jpg ├── 4-4-1-cull-front.jpg ├── 4-5-1-render-to-texture.jpg ├── 4-5-2-inversion.jpg ├── 4-5-3-grayscale.jpg ├── 4-5-4-sharpen.jpg ├── 4-5-5-blur.jpg ├── 4-5-6-edge-detection.jpg ├── 4-6-1-skybox.jpg ├── 4-6-2-reflection-cube.jpg ├── 4-6-3-reflection-backpack.jpg ├── 4-6-4-refraction-cube.jpg ├── 4-6-5-refraction-backpack.jpg ├── 4-8-1-point-size.jpg ├── 4-8-2-frag-coord.jpg ├── 4-8-3-front-facing.jpg ├── 4-8-4-uniform-buffers.jpg ├── 4-9-1-lines.jpg ├── 4-9-2-houses.jpg ├── 4-9-3-exploding-object.jpg ├── 4-9-4-visualizing-normals.jpg ├── 5-1-1-blinn-phong.jpg ├── 5-2-1-gamma-correction.jpg ├── 5-3-1-mapping-depth.jpg ├── 5-3-2-rendering-shadows.jpg ├── 5-3-3-improved-shadows.jpg ├── 5-4-1-omnidirectional-depth.jpg ├── 5-4-2-omnidirectional-shadows.jpg ├── 5-4-3-omnidirectional-PCF.jpg ├── 5-5-1-normal-mapping.jpg ├── 5-5-2-tangent-space.jpg ├── 5-5-3-complex-object.jpg ├── dummy.jpg ├── favicon.png ├── fontello.woff ├── fontello.woff2 ├── index.html ├── shell.html └── wasm.html /.gitignore: -------------------------------------------------------------------------------- 1 | #>fips 2 | # this area is managed by fips, do not edit 3 | .fips-* 4 | *.pyc 5 | .vscode/ 6 | .idea/ 7 | # mkdir fips-workspace 32 | > cd fips-workspace 33 | > git clone https://github.com/GeertArien/learnopengl-examples.git 34 | > cd learnopengl-examples 35 | > ./fips build 36 | > ./fips run 1-3-1-rendering 37 | ``` 38 | 39 | #### Targets 40 | 41 | To get a list of targets: 42 | 43 | ```bash 44 | > ./fips list targets 45 | ``` 46 | 47 | To run a specific target: 48 | 49 | ```bash 50 | > ./fips run 3-1-2-backpack-lights 51 | ``` 52 | 53 | 54 | #### Web Builds 55 | 56 | To enable web builds you need to setup the [emscripten](https://emscripten.org/index.html) SDK and select 57 | one of the webgl2 configs: _webgl2-wasm-ninja-debug_ or _webgl2-wasm-ninja-release_. 58 | 59 | ```bash 60 | > ./fips setup emscripten 61 | > ./fips set config webgl2-wasm-ninja-debug 62 | > ./fips build 63 | ``` 64 | 65 | 66 | ## IDE Integration 67 | 68 | Fips supports CLion, Visual Studio, Visual Studio Code and XCode as provided by cmake: 69 | 70 | ```bash 71 | > ./fips set config linux-clion-debug 72 | > ./fips gen 73 | > ./fips open 74 | ``` 75 | 76 | ```bash 77 | > ./fips set config win64-vstudio-debug 78 | > ./fips gen 79 | > ./fips open 80 | ``` 81 | 82 | ```bash 83 | > ./fips set config win64-vscode-debug 84 | > ./fips gen 85 | > ./fips open 86 | ``` 87 | 88 | ```bash 89 | > ./fips set config osx-xcode-debug 90 | > ./fips gen 91 | > ./fips open 92 | ``` 93 | -------------------------------------------------------------------------------- /fips: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """fips main entry""" 3 | import os 4 | import sys 5 | import subprocess 6 | proj_path = os.path.dirname(os.path.abspath(__file__)) 7 | fips_path = os.path.dirname(proj_path) + '/fips' 8 | if not os.path.isdir(fips_path) : 9 | print("\033[93m=== cloning fips build system to '{}':\033[0m".format(fips_path)) 10 | subprocess.call(['git', 'clone', 'https://github.com/floooh/fips.git', fips_path]) 11 | sys.path.insert(0,fips_path) 12 | try : 13 | from mod import fips 14 | except ImportError : 15 | print("\033[91m[ERROR]\033[0m failed to initialize fips build system in '{}'".format(proj_path)) 16 | sys.exit(10) 17 | fips.run(fips_path, proj_path, sys.argv) 18 | -------------------------------------------------------------------------------- /fips-files/configs/webgl2-wasm-ninja-debug.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: emscripten 3 | generator: Ninja 4 | build_tool: ninja 5 | build_type: Debug 6 | cmake-toolchain: emscripten.toolchain.cmake 7 | defines: 8 | FIPS_NO_ASSERTS_IN_RELEASE: ON 9 | FIPS_EMSCRIPTEN_USE_WASM: ON 10 | FIPS_EMSCRIPTEN_USE_WEBGL2: ON 11 | FIPS_EMSCRIPTEN_MEM_INIT_METHOD: 0 12 | FIPS_EMSCRIPTEN_USE_EMMALLOC: ON 13 | FIPS_EMSCRIPTEN_RELATIVE_SHELL_HTML: "webpage/shell.html" 14 | -------------------------------------------------------------------------------- /fips-files/configs/webgl2-wasm-ninja-release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: emscripten 3 | generator: Ninja 4 | build_tool: ninja 5 | build_type: Release 6 | cmake-toolchain: emscripten.toolchain.cmake 7 | defines: 8 | FIPS_NO_ASSERTS_IN_RELEASE: ON 9 | FIPS_EMSCRIPTEN_USE_WASM: ON 10 | FIPS_EMSCRIPTEN_USE_WEBGL2: ON 11 | FIPS_EMSCRIPTEN_MEM_INIT_METHOD: 0 12 | FIPS_EMSCRIPTEN_USE_EMMALLOC: ON 13 | FIPS_EMSCRIPTEN_USE_CLOSURE: ON 14 | FIPS_EMSCRIPTEN_RELATIVE_SHELL_HTML: "webpage/shell.html" 15 | -------------------------------------------------------------------------------- /fips.cmd: -------------------------------------------------------------------------------- 1 | @python fips %* 2 | 3 | -------------------------------------------------------------------------------- /fips.yml: -------------------------------------------------------------------------------- 1 | # 2 | # learnopengl-examples 3 | # 4 | --- 5 | policies: 6 | no_auto_import: true 7 | imports: 8 | sokol: 9 | git: https://github.com/floooh/sokol 10 | branch: pre-feb2021-api-changes 11 | sokol-tools-bin: 12 | git: https://github.com/floooh/sokol-tools-bin 13 | branch: pre-feb2021-api-changes 14 | fips-utils: 15 | git: https://github.com/fips-libs/fips-utils -------------------------------------------------------------------------------- /libs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # select the 3D backend for sokol_gfx.h and sokol_app.h 2 | # the sokol_config() macro is in the top-level CMakeLists.txt file! 3 | sokol_config() 4 | 5 | add_subdirectory(sokol) 6 | -------------------------------------------------------------------------------- /libs/cgltf/readme.txt: -------------------------------------------------------------------------------- 1 | see: https://github.com/jkuhlmann/cgltf 2 | 3 | -------------------------------------------------------------------------------- /libs/fast_obj/readme.txt: -------------------------------------------------------------------------------- 1 | repo: https://github.com/thisistherk/fast_obj 2 | commit: 48127431ad7ce34b33ab47198d3699e2ea6ee2cb 3 | 4 | lopgl_fast_obj.h is a modified version of fast_obj.h: 5 | - api takes buffers instead of file path 6 | - separate api call to load in material files 7 | 8 | modifications were required for web builds 9 | -------------------------------------------------------------------------------- /libs/hmm/readme.txt: -------------------------------------------------------------------------------- 1 | https://github.com/HandmadeMath/Handmade-Math -------------------------------------------------------------------------------- /libs/sokol/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # the sokol implementations library 2 | fips_begin_lib(sokol) 3 | fips_vs_warning_level(4) 4 | if (FIPS_OSX) 5 | fips_files(sokol.m) 6 | if (FIPS_IOS) 7 | if (SOKOL_USE_METAL) 8 | fips_frameworks_osx(UIKit Metal MetalKit) 9 | else() 10 | fips_frameworks_osx(UIKit OpenGLES GLKit) 11 | endif() 12 | else() 13 | if (SOKOL_USE_METAL) 14 | fips_frameworks_osx(Cocoa QuartzCore Metal MetalKit) 15 | else() 16 | fips_frameworks_osx(Cocoa QuartzCore OpenGL) 17 | endif() 18 | endif() 19 | else() 20 | fips_files(sokol.c) 21 | if (FIPS_ANDROID) 22 | fips_libs(GLESv3 EGL OpenSLES log android) 23 | elseif (FIPS_LINUX) 24 | fips_libs(X11 Xi Xcursor GL m dl) 25 | endif() 26 | endif() 27 | fips_end_lib() 28 | -------------------------------------------------------------------------------- /libs/sokol/sokol.c: -------------------------------------------------------------------------------- 1 | #define SOKOL_IMPL 2 | #if defined(_WIN32) 3 | #include 4 | #define SOKOL_LOG(s) OutputDebugStringA(s) 5 | /* don't complain about unused variables at /W4 when assert() is a NOP */ 6 | #if defined(NDEBUG) 7 | #define SOKOL_ASSERT(x) ((void)(x)) 8 | #endif 9 | #endif 10 | /* this is only needed for the debug-inspection headers */ 11 | #define SOKOL_TRACE_HOOKS 12 | /* sokol 3D-API defines are provided by build options */ 13 | #include "sokol_app.h" 14 | #include "sokol_gfx.h" 15 | #include "sokol_glue.h" 16 | #include "sokol_time.h" 17 | #include "sokol_fetch.h" 18 | -------------------------------------------------------------------------------- /libs/sokol/sokol.m: -------------------------------------------------------------------------------- 1 | #define SOKOL_IMPL 2 | /* this is only needed for the debug-inspection headers */ 3 | #define SOKOL_TRACE_HOOKS 4 | /* sokol 3D-API defines are provided by build options */ 5 | #include "sokol_app.h" 6 | #include "sokol_gfx.h" 7 | #include "sokol_glue.h" 8 | #include "sokol_time.h" 9 | #include "sokol_fetch.h" 10 | -------------------------------------------------------------------------------- /libs/stb/readme.txt: -------------------------------------------------------------------------------- 1 | see: https://github.com/nothings/stb 2 | 3 | -------------------------------------------------------------------------------- /src/1-3-hello-window/1-rendering.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 1-3-1-rendering 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_gfx.h" 5 | #include "sokol_app.h" 6 | #include "sokol_glue.h" 7 | 8 | static struct { 9 | sg_pass_action pass_action; 10 | } state; 11 | 12 | void init(void) { 13 | sg_setup(&(sg_desc){ 14 | .context = sapp_sgcontext() 15 | }); 16 | 17 | state.pass_action = (sg_pass_action) { 18 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.2f, 0.3f, 0.3f, 1.0f} } 19 | }; 20 | } 21 | 22 | void frame(void) { 23 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 24 | sg_end_pass(); 25 | sg_commit(); 26 | } 27 | 28 | void cleanup(void) { 29 | sg_shutdown(); 30 | } 31 | 32 | void event(const sapp_event* e) { 33 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 34 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 35 | sapp_request_quit(); 36 | } 37 | } 38 | } 39 | 40 | sapp_desc sokol_main(int argc, char* argv[]) { 41 | return (sapp_desc){ 42 | .init_cb = init, 43 | .frame_cb = frame, 44 | .cleanup_cb = cleanup, 45 | .event_cb = event, 46 | .width = 800, 47 | .height = 600, 48 | .gl_force_gles2 = true, 49 | .window_title = "Rendering - LearnOpenGL", 50 | }; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/1-3-hello-window/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(1-3-1-rendering windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-rendering.c) 4 | fips_deps(sokol) 5 | fips_end_app() 6 | -------------------------------------------------------------------------------- /src/1-4-hello-triangle/1-triangle.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 1-4-1-triangle 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #include "1-triangle.glsl.h" 8 | 9 | /* application state */ 10 | static struct { 11 | sg_pipeline pip; 12 | sg_bindings bind; 13 | sg_pass_action pass_action; 14 | } state; 15 | 16 | static void init(void) { 17 | sg_setup(&(sg_desc){ 18 | .context = sapp_sgcontext() 19 | }); 20 | 21 | /* create shader from code-generated sg_shader_desc */ 22 | sg_shader shd = sg_make_shader(simple_shader_desc()); 23 | 24 | /* a vertex buffer with 3 vertices */ 25 | float vertices[] = { 26 | // positions 27 | -0.5f, -0.5f, 0.0f, // bottom left 28 | 0.5f, -0.5f, 0.0f, // bottom right 29 | 0.0f, 0.5f, 0.0f // top 30 | }; 31 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 32 | .size = sizeof(vertices), 33 | .content = vertices, 34 | .label = "triangle-vertices" 35 | }); 36 | 37 | /* create a pipeline object (default render states are fine for triangle) */ 38 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 39 | .shader = shd, 40 | /* if the vertex layout doesn't have gaps, don't need to provide strides and offsets */ 41 | .layout = { 42 | .attrs = { 43 | [ATTR_vs_position].format = SG_VERTEXFORMAT_FLOAT3 44 | } 45 | }, 46 | .label = "triangle-pipeline" 47 | }); 48 | 49 | /* a pass action to clear framebuffer */ 50 | state.pass_action = (sg_pass_action) { 51 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.2f, 0.3f, 0.3f, 1.0f} } 52 | }; 53 | } 54 | 55 | void frame(void) { 56 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 57 | sg_apply_pipeline(state.pip); 58 | sg_apply_bindings(&state.bind); 59 | sg_draw(0, 3, 1); 60 | sg_end_pass(); 61 | sg_commit(); 62 | } 63 | 64 | void cleanup(void) { 65 | sg_shutdown(); 66 | } 67 | 68 | void event(const sapp_event* e) { 69 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 70 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 71 | sapp_request_quit(); 72 | } 73 | } 74 | } 75 | 76 | sapp_desc sokol_main(int argc, char* argv[]) { 77 | return (sapp_desc){ 78 | .init_cb = init, 79 | .frame_cb = frame, 80 | .cleanup_cb = cleanup, 81 | .event_cb = event, 82 | .width = 800, 83 | .height = 600, 84 | .gl_force_gles2 = true, 85 | .window_title = "Triangle - LearnOpenGL", 86 | }; 87 | } 88 | -------------------------------------------------------------------------------- /src/1-4-hello-triangle/1-triangle.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec4 position; 3 | 4 | void main() { 5 | gl_Position = vec4(position.x, position.y, position.z, 1.0); 6 | } 7 | @end 8 | 9 | @fs fs 10 | out vec4 FragColor; 11 | 12 | void main() { 13 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 14 | } 15 | @end 16 | 17 | @program simple vs fs 18 | -------------------------------------------------------------------------------- /src/1-4-hello-triangle/2-quad.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 1-4-2-quad 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #include "2-quad.glsl.h" 8 | 9 | /* application state */ 10 | static struct { 11 | sg_pipeline pip; 12 | sg_bindings bind; 13 | sg_pass_action pass_action; 14 | } state; 15 | 16 | static void init(void) { 17 | sg_setup(&(sg_desc){ 18 | .context = sapp_sgcontext() 19 | }); 20 | 21 | /* create shader from code-generated sg_shader_desc */ 22 | sg_shader shd = sg_make_shader(simple_shader_desc()); 23 | 24 | 25 | /* a vertex buffer with 4 vertices */ 26 | float vertices[] = { 27 | // positions 28 | 0.5f, 0.5f, 0.0f, // top right 29 | 0.5f, -0.5f, 0.0f, // bottom right 30 | -0.5f, -0.5f, 0.0f, // bottom left 31 | -0.5f, 0.5f, 0.0f // top left 32 | }; 33 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 34 | .size = sizeof(vertices), 35 | .content = vertices, 36 | .label = "quad-vertices" 37 | }); 38 | 39 | /* an index buffer with 2 triangles */ 40 | uint16_t indices[] = { 41 | 0, 1, 3, // first triangle 42 | 1, 2, 3 // second triangle 43 | }; 44 | state.bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){ 45 | .type = SG_BUFFERTYPE_INDEXBUFFER, 46 | .size = sizeof(indices), 47 | .content = indices, 48 | .label = "quad-indices" 49 | }); 50 | 51 | /* a pipeline state object */ 52 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 53 | .shader = shd, 54 | .index_type = SG_INDEXTYPE_UINT16, 55 | .layout = { 56 | .attrs = { 57 | [ATTR_vs_position].format = SG_VERTEXFORMAT_FLOAT3 58 | } 59 | }, 60 | .label = "quad-pipeline" 61 | }); 62 | 63 | /* a pass action to clear framebuffer */ 64 | state.pass_action = (sg_pass_action) { 65 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.2f, 0.3f, 0.3f, 1.0f} } 66 | }; 67 | } 68 | 69 | void frame(void) { 70 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 71 | sg_apply_pipeline(state.pip); 72 | sg_apply_bindings(&state.bind); 73 | sg_draw(0, 6, 1); 74 | sg_end_pass(); 75 | sg_commit(); 76 | } 77 | 78 | void cleanup(void) { 79 | sg_shutdown(); 80 | } 81 | 82 | void event(const sapp_event* e) { 83 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 84 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 85 | sapp_request_quit(); 86 | } 87 | } 88 | } 89 | 90 | sapp_desc sokol_main(int argc, char* argv[]) { 91 | return (sapp_desc){ 92 | .init_cb = init, 93 | .frame_cb = frame, 94 | .cleanup_cb = cleanup, 95 | .event_cb = event, 96 | .width = 800, 97 | .height = 600, 98 | .gl_force_gles2 = true, 99 | .window_title = "Quad - LearnOpenGL", 100 | }; 101 | } 102 | -------------------------------------------------------------------------------- /src/1-4-hello-triangle/2-quad.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec4 position; 3 | 4 | void main() { 5 | gl_Position = vec4(position.x, position.y, position.z, 1.0); 6 | } 7 | @end 8 | 9 | @fs fs 10 | out vec4 FragColor; 11 | 12 | void main() { 13 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 14 | } 15 | @end 16 | 17 | @program simple vs fs 18 | -------------------------------------------------------------------------------- /src/1-4-hello-triangle/3-quad-wireframe.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 1-4-3-quad-wireframe 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #include "3-quad-wireframe.glsl.h" 8 | 9 | /* application state */ 10 | static struct { 11 | sg_pipeline pip; 12 | sg_bindings bind; 13 | sg_pass_action pass_action; 14 | } state; 15 | 16 | static void init(void) { 17 | sg_setup(&(sg_desc){ 18 | .context = sapp_sgcontext() 19 | }); 20 | 21 | /* create shader from code-generated sg_shader_desc */ 22 | sg_shader shd = sg_make_shader(simple_shader_desc()); 23 | 24 | /* a vertex buffer with 4 vertices */ 25 | float vertices[] = { 26 | // positions 27 | 0.5f, 0.5f, 0.0f, // top right 28 | 0.5f, -0.5f, 0.0f, // bottom right 29 | -0.5f, -0.5f, 0.0f, // bottom left 30 | -0.5f, 0.5f, 0.0f // top left 31 | }; 32 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 33 | .size = sizeof(vertices), 34 | .content = vertices, 35 | .label = "quad-vertices" 36 | }); 37 | 38 | /* an index buffer with 2 triangles */ 39 | uint16_t indices[] = { 40 | 0, 1, 1, 3, 3, 0, // first triangle 41 | 1, 2, 2, 3, 3, 1 // second triangle 42 | }; 43 | state.bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){ 44 | .type = SG_BUFFERTYPE_INDEXBUFFER, 45 | .size = sizeof(indices), 46 | .content = indices, 47 | .label = "quad-indices" 48 | }); 49 | 50 | /* a pipeline state object */ 51 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 52 | .shader = shd, 53 | .index_type = SG_INDEXTYPE_UINT16, 54 | .primitive_type = SG_PRIMITIVETYPE_LINES, 55 | .layout = { 56 | .attrs = { 57 | [ATTR_vs_position].format = SG_VERTEXFORMAT_FLOAT3 58 | } 59 | }, 60 | .label = "quad-pipeline" 61 | }); 62 | 63 | /* a pass action to clear framebuffer */ 64 | state.pass_action = (sg_pass_action) { 65 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.2f, 0.3f, 0.3f, 1.0f} } 66 | }; 67 | } 68 | 69 | void frame(void) { 70 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 71 | sg_apply_pipeline(state.pip); 72 | sg_apply_bindings(&state.bind); 73 | sg_draw(0, 12, 1); 74 | sg_end_pass(); 75 | sg_commit(); 76 | } 77 | 78 | void cleanup(void) { 79 | sg_shutdown(); 80 | } 81 | 82 | void event(const sapp_event* e) { 83 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 84 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 85 | sapp_request_quit(); 86 | } 87 | } 88 | } 89 | 90 | sapp_desc sokol_main(int argc, char* argv[]) { 91 | return (sapp_desc){ 92 | .init_cb = init, 93 | .frame_cb = frame, 94 | .cleanup_cb = cleanup, 95 | .event_cb = event, 96 | .width = 800, 97 | .height = 600, 98 | .gl_force_gles2 = true, 99 | .window_title = "Quad Wireframe - LearnOpenGL", 100 | }; 101 | } 102 | -------------------------------------------------------------------------------- /src/1-4-hello-triangle/3-quad-wireframe.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec4 position; 3 | 4 | void main() { 5 | gl_Position = vec4(position.x, position.y, position.z, 1.0); 6 | } 7 | @end 8 | 9 | @fs fs 10 | out vec4 FragColor; 11 | 12 | void main() { 13 | FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); 14 | } 15 | @end 16 | 17 | @program simple vs fs 18 | -------------------------------------------------------------------------------- /src/1-4-hello-triangle/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(1-4-1-triangle windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-triangle.c) 4 | sokol_shader(1-triangle.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(1-4-2-quad windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-quad.c) 11 | sokol_shader(2-quad.glsl ${slang}) 12 | fips_deps(sokol) 13 | fips_end_app() 14 | 15 | fips_begin_app(1-4-3-quad-wireframe windowed) 16 | fips_vs_warning_level(3) 17 | fips_files(3-quad-wireframe.c) 18 | sokol_shader(3-quad-wireframe.glsl ${slang}) 19 | fips_deps(sokol) 20 | fips_end_app() 21 | -------------------------------------------------------------------------------- /src/1-5-shaders/1-in-out.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 1-5-1-in-out 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #include "1-in-out.glsl.h" 8 | 9 | /* application state */ 10 | static struct { 11 | sg_pipeline pip; 12 | sg_bindings bind; 13 | sg_pass_action pass_action; 14 | } state; 15 | 16 | static void init(void) { 17 | sg_setup(&(sg_desc){ 18 | .context = sapp_sgcontext() 19 | }); 20 | 21 | /* create shader from code-generated sg_shader_desc */ 22 | sg_shader shd = sg_make_shader(simple_shader_desc()); 23 | 24 | /* a vertex buffer with 3 vertices */ 25 | float vertices[] = { 26 | // positions 27 | -0.5f, -0.5f, 0.0f, // bottom left 28 | 0.5f, -0.5f, 0.0f, // bottom right 29 | 0.0f, 0.5f, 0.0f // top 30 | }; 31 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 32 | .size = sizeof(vertices), 33 | .content = vertices, 34 | .label = "triangle-vertices" 35 | }); 36 | 37 | /* create a pipeline object (default render states are fine for triangle) */ 38 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 39 | .shader = shd, 40 | /* if the vertex layout doesn't have gaps, don't need to provide strides and offsets */ 41 | .layout = { 42 | .attrs = { 43 | [ATTR_vs_position].format = SG_VERTEXFORMAT_FLOAT3 44 | } 45 | }, 46 | .label = "triangle-pipeline" 47 | }); 48 | 49 | /* a pass action to clear framebuffer */ 50 | state.pass_action = (sg_pass_action) { 51 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.2f, 0.3f, 0.3f, 1.0f} } 52 | }; 53 | } 54 | 55 | void frame(void) { 56 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 57 | sg_apply_pipeline(state.pip); 58 | sg_apply_bindings(&state.bind); 59 | sg_draw(0, 3, 1); 60 | sg_end_pass(); 61 | sg_commit(); 62 | } 63 | 64 | void cleanup(void) { 65 | sg_shutdown(); 66 | } 67 | 68 | void event(const sapp_event* e) { 69 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 70 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 71 | sapp_request_quit(); 72 | } 73 | } 74 | } 75 | 76 | sapp_desc sokol_main(int argc, char* argv[]) { 77 | return (sapp_desc){ 78 | .init_cb = init, 79 | .frame_cb = frame, 80 | .cleanup_cb = cleanup, 81 | .event_cb = event, 82 | .width = 800, 83 | .height = 600, 84 | .gl_force_gles2 = true, 85 | .window_title = "In Out - LearnOpenGL", 86 | }; 87 | } 88 | -------------------------------------------------------------------------------- /src/1-5-shaders/1-in-out.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec4 position; 3 | 4 | out vec4 vertexColor; // specify a color output to the fragment shader 5 | 6 | void main() { 7 | gl_Position = vec4(position.x, position.y, position.z, 1.0); 8 | vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // set the output variable to a dark-red color 9 | } 10 | @end 11 | 12 | @fs fs 13 | in vec4 vertexColor; // the input variable from the vertex shader (same name and same type) 14 | 15 | out vec4 FragColor; 16 | 17 | void main() { 18 | FragColor = vertexColor; 19 | } 20 | @end 21 | 22 | @program simple vs fs 23 | -------------------------------------------------------------------------------- /src/1-5-shaders/2-uniforms.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 1-5-2-uniforms 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #include "sokol_time.h" 8 | #include "2-uniforms.glsl.h" 9 | #include "math.h" 10 | 11 | /* application state */ 12 | static struct { 13 | sg_pipeline pip; 14 | sg_bindings bind; 15 | sg_pass_action pass_action; 16 | } state; 17 | 18 | static void init(void) { 19 | sg_setup(&(sg_desc){ 20 | .context = sapp_sgcontext() 21 | }); 22 | 23 | /* initialize sokol_time */ 24 | stm_setup(); 25 | 26 | /* create shader from code-generated sg_shader_desc */ 27 | sg_shader shd = sg_make_shader(simple_shader_desc()); 28 | 29 | /* a vertex buffer with 3 vertices */ 30 | float vertices[] = { 31 | // positions 32 | -0.5f, -0.5f, 0.0f, // bottom left 33 | 0.5f, -0.5f, 0.0f, // bottom right 34 | 0.0f, 0.5f, 0.0f // top 35 | }; 36 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 37 | .size = sizeof(vertices), 38 | .content = vertices, 39 | .label = "triangle-vertices" 40 | }); 41 | 42 | /* create a pipeline object (default render states are fine for triangle) */ 43 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 44 | .shader = shd, 45 | /* if the vertex layout doesn't have gaps, don't need to provide strides and offsets */ 46 | .layout = { 47 | .attrs = { 48 | [ATTR_vs_position].format = SG_VERTEXFORMAT_FLOAT3 49 | } 50 | }, 51 | .label = "triangle-pipeline" 52 | }); 53 | 54 | /* a pass action to clear framebuffer */ 55 | state.pass_action = (sg_pass_action) { 56 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.2f, 0.3f, 0.3f, 1.0f} } 57 | }; 58 | } 59 | 60 | void frame(void) { 61 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 62 | sg_apply_pipeline(state.pip); 63 | sg_apply_bindings(&state.bind); 64 | 65 | float now = (float) stm_sec(stm_now()); 66 | float greenValue = (sinf(now) / 2.0f) + 0.5f; 67 | 68 | fs_params_t fs_params = { 69 | .ourColor = { 0.f, greenValue, 0.f, 1.f } 70 | }; 71 | sg_apply_uniforms(SG_SHADERSTAGE_FS, SLOT_fs_params, &fs_params, sizeof(fs_params)); 72 | 73 | sg_draw(0, 3, 1); 74 | sg_end_pass(); 75 | sg_commit(); 76 | } 77 | 78 | void cleanup(void) { 79 | sg_shutdown(); 80 | } 81 | 82 | void event(const sapp_event* e) { 83 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 84 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 85 | sapp_request_quit(); 86 | } 87 | } 88 | } 89 | 90 | sapp_desc sokol_main(int argc, char* argv[]) { 91 | return (sapp_desc){ 92 | .init_cb = init, 93 | .frame_cb = frame, 94 | .cleanup_cb = cleanup, 95 | .event_cb = event, 96 | .width = 800, 97 | .height = 600, 98 | .gl_force_gles2 = true, 99 | .window_title = "Uniforms - LearnOpenGL", 100 | }; 101 | } 102 | -------------------------------------------------------------------------------- /src/1-5-shaders/2-uniforms.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec4 position; 3 | 4 | void main() { 5 | gl_Position = vec4(position.x, position.y, position.z, 1.0); 6 | } 7 | @end 8 | 9 | @fs fs 10 | uniform fs_params { 11 | vec4 ourColor; 12 | }; 13 | 14 | out vec4 FragColor; 15 | 16 | void main() { 17 | FragColor = ourColor; 18 | } 19 | @end 20 | 21 | @program simple vs fs 22 | -------------------------------------------------------------------------------- /src/1-5-shaders/3-attributes.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 1-5-3-attributes 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #include "3-attributes.glsl.h" 8 | 9 | /* application state */ 10 | static struct { 11 | sg_pipeline pip; 12 | sg_bindings bind; 13 | sg_pass_action pass_action; 14 | } state; 15 | 16 | static void init(void) { 17 | sg_setup(&(sg_desc){ 18 | .context = sapp_sgcontext() 19 | }); 20 | 21 | /* create shader from code-generated sg_shader_desc */ 22 | sg_shader shd = sg_make_shader(simple_shader_desc()); 23 | 24 | /* a vertex buffer with 3 vertices */ 25 | float vertices[] = { 26 | // positions // colors 27 | 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right 28 | -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left 29 | 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top 30 | }; 31 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 32 | .size = sizeof(vertices), 33 | .content = vertices, 34 | .label = "triangle-vertices" 35 | }); 36 | 37 | /* create a pipeline object (default render states are fine for triangle) */ 38 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 39 | .shader = shd, 40 | /* if the vertex layout doesn't have gaps, don't need to provide strides and offsets */ 41 | .layout = { 42 | .attrs = { 43 | [ATTR_vs_position].format = SG_VERTEXFORMAT_FLOAT3, 44 | [ATTR_vs_aColor].format = SG_VERTEXFORMAT_FLOAT3 45 | } 46 | }, 47 | .label = "triangle-pipeline" 48 | }); 49 | 50 | /* a pass action to clear framebuffer */ 51 | state.pass_action = (sg_pass_action) { 52 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.2f, 0.3f, 0.3f, 1.0f} } 53 | }; 54 | } 55 | 56 | void frame(void) { 57 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 58 | sg_apply_pipeline(state.pip); 59 | sg_apply_bindings(&state.bind); 60 | sg_draw(0, 3, 1); 61 | sg_end_pass(); 62 | sg_commit(); 63 | } 64 | 65 | void cleanup(void) { 66 | sg_shutdown(); 67 | } 68 | 69 | void event(const sapp_event* e) { 70 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 71 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 72 | sapp_request_quit(); 73 | } 74 | } 75 | } 76 | 77 | sapp_desc sokol_main(int argc, char* argv[]) { 78 | return (sapp_desc){ 79 | .init_cb = init, 80 | .frame_cb = frame, 81 | .cleanup_cb = cleanup, 82 | .event_cb = event, 83 | .width = 800, 84 | .height = 600, 85 | .gl_force_gles2 = true, 86 | .window_title = "Attributes - LearnOpenGL", 87 | }; 88 | } 89 | -------------------------------------------------------------------------------- /src/1-5-shaders/3-attributes.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec3 position; 3 | in vec3 aColor; // the color variable 4 | 5 | out vec3 ourColor; // output a color to the fragment shader 6 | 7 | void main() { 8 | gl_Position = vec4(position.x, position.y, position.z, 1.0); 9 | ourColor = aColor; // set ourColor to the input color we got from the vertex data 10 | } 11 | @end 12 | 13 | @fs fs 14 | in vec3 ourColor; 15 | 16 | out vec4 FragColor; 17 | 18 | void main() { 19 | FragColor = vec4(ourColor, 1.0); 20 | } 21 | @end 22 | 23 | @program simple vs fs 24 | -------------------------------------------------------------------------------- /src/1-5-shaders/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(1-5-1-in-out windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-in-out.c) 4 | sokol_shader(1-in-out.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(1-5-2-uniforms windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-uniforms.c) 11 | sokol_shader(2-uniforms.glsl ${slang}) 12 | fips_deps(sokol) 13 | fips_end_app() 14 | 15 | fips_begin_app(1-5-3-attributes windowed) 16 | fips_vs_warning_level(3) 17 | fips_files(3-attributes) 18 | sokol_shader(3-attributes.glsl ${slang}) 19 | fips_deps(sokol) 20 | fips_end_app() 21 | -------------------------------------------------------------------------------- /src/1-6-textures/1-texture.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec3 position; 3 | in vec3 aColor; 4 | in vec2 aTexCoord; 5 | 6 | out vec3 ourColor; 7 | out vec2 TexCoord; 8 | 9 | void main() { 10 | gl_Position = vec4(position, 1.0); 11 | ourColor = aColor; 12 | TexCoord = aTexCoord; 13 | } 14 | @end 15 | 16 | @fs fs 17 | out vec4 FragColor; 18 | 19 | in vec3 ourColor; 20 | in vec2 TexCoord; 21 | 22 | uniform sampler2D ourTexture; 23 | 24 | void main() { 25 | FragColor = texture(ourTexture, TexCoord); 26 | } 27 | @end 28 | 29 | @program simple vs fs 30 | -------------------------------------------------------------------------------- /src/1-6-textures/2-texture-blend.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec3 position; 3 | in vec3 aColor; 4 | in vec2 aTexCoord; 5 | 6 | out vec3 ourColor; 7 | out vec2 TexCoord; 8 | 9 | void main() { 10 | gl_Position = vec4(position, 1.0); 11 | ourColor = aColor; 12 | TexCoord = aTexCoord; 13 | } 14 | @end 15 | 16 | @fs fs 17 | out vec4 FragColor; 18 | 19 | in vec3 ourColor; 20 | in vec2 TexCoord; 21 | 22 | uniform sampler2D ourTexture; 23 | 24 | void main() { 25 | FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0); 26 | } 27 | @end 28 | 29 | @program simple vs fs 30 | -------------------------------------------------------------------------------- /src/1-6-textures/3-multiple-textures.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec3 position; 3 | in vec3 aColor; 4 | in vec2 aTexCoord; 5 | 6 | out vec3 ourColor; 7 | out vec2 TexCoord; 8 | 9 | void main() { 10 | gl_Position = vec4(position, 1.0); 11 | ourColor = aColor; 12 | TexCoord = aTexCoord; 13 | } 14 | @end 15 | 16 | @fs fs 17 | out vec4 FragColor; 18 | 19 | in vec3 ourColor; 20 | in vec2 TexCoord; 21 | 22 | uniform sampler2D texture1; 23 | uniform sampler2D texture2; 24 | 25 | void main() { 26 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 27 | } 28 | @end 29 | 30 | @program simple vs fs 31 | -------------------------------------------------------------------------------- /src/1-6-textures/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(1-6-1-texture windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-texture.c) 4 | sokol_shader(1-texture.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(1-6-2-texture-blend windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-texture-blend.c) 12 | sokol_shader(2-texture-blend.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(1-6-3-multiple-textures windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-multiple-textures.c) 20 | sokol_shader(3-multiple-textures.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | -------------------------------------------------------------------------------- /src/1-6-textures/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container.jpg 7 | - awesomeface.png 8 | -------------------------------------------------------------------------------- /src/1-7-transformations/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(1-7-1-scale-rotate windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-scale-rotate.c) 4 | sokol_shader(transformations.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(1-7-2-rotate-translate windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-rotate-translate.c) 12 | sokol_shader(transformations.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | -------------------------------------------------------------------------------- /src/1-7-transformations/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container.jpg 7 | - awesomeface.png 8 | -------------------------------------------------------------------------------- /src/1-7-transformations/transformations.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs 4 | in vec3 position; 5 | in vec2 aTexCoord; 6 | 7 | out vec2 TexCoord; 8 | 9 | uniform vs_params { 10 | mat4 transform; 11 | }; 12 | 13 | void main() { 14 | gl_Position = transform * vec4(position, 1.0); 15 | TexCoord = aTexCoord; 16 | } 17 | @end 18 | 19 | @fs fs 20 | out vec4 FragColor; 21 | 22 | in vec2 TexCoord; 23 | 24 | uniform sampler2D texture1; 25 | uniform sampler2D texture2; 26 | 27 | void main() { 28 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 29 | } 30 | @end 31 | 32 | @program simple vs fs 33 | -------------------------------------------------------------------------------- /src/1-8-coordinate-systems/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(1-8-1-plane windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-plane.c) 4 | sokol_shader(shaders.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(1-8-2-cube windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-cube.c) 12 | sokol_shader(shaders.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(1-8-3-more-cubes windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-more-cubes.c) 20 | sokol_shader(shaders.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | -------------------------------------------------------------------------------- /src/1-8-coordinate-systems/shaders.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs 4 | in vec3 aPos; 5 | in vec2 aTexCoord; 6 | 7 | out vec2 TexCoord; 8 | 9 | uniform vs_params { 10 | mat4 model; 11 | mat4 view; 12 | mat4 projection; 13 | }; 14 | 15 | void main() { 16 | // note that we read the multiplication from right to left 17 | gl_Position = projection * view * model * vec4(aPos, 1.0); 18 | TexCoord = aTexCoord; 19 | } 20 | @end 21 | 22 | @fs fs 23 | out vec4 FragColor; 24 | 25 | in vec2 TexCoord; 26 | 27 | uniform sampler2D texture1; 28 | uniform sampler2D texture2; 29 | 30 | void main() { 31 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 32 | } 33 | @end 34 | 35 | @program simple vs fs 36 | -------------------------------------------------------------------------------- /src/1-8-coordinate-systems/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container.jpg 7 | - awesomeface.png 8 | -------------------------------------------------------------------------------- /src/1-9-camera/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(1-9-1-lookat windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-lookat.c) 4 | sokol_shader(shaders.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(1-9-2-walk windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-walk.c) 12 | sokol_shader(shaders.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(1-9-3-look windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-look.c) 20 | sokol_shader(shaders.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | -------------------------------------------------------------------------------- /src/1-9-camera/shaders.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs 4 | in vec3 aPos; 5 | in vec2 aTexCoord; 6 | 7 | out vec2 TexCoord; 8 | 9 | uniform vs_params { 10 | mat4 model; 11 | mat4 view; 12 | mat4 projection; 13 | }; 14 | 15 | void main() { 16 | // note that we read the multiplication from right to left 17 | gl_Position = projection * view * model * vec4(aPos, 1.0); 18 | TexCoord = aTexCoord; 19 | } 20 | @end 21 | 22 | @fs fs 23 | out vec4 FragColor; 24 | 25 | in vec2 TexCoord; 26 | 27 | uniform sampler2D texture1; 28 | uniform sampler2D texture2; 29 | 30 | void main() { 31 | FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); 32 | } 33 | @end 34 | 35 | @program simple vs fs 36 | -------------------------------------------------------------------------------- /src/1-9-camera/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container.jpg 7 | - awesomeface.png 8 | -------------------------------------------------------------------------------- /src/2-1-colors/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(2-1-1-scene windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-scene.c) 4 | sokol_shader(shaders.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | -------------------------------------------------------------------------------- /src/2-1-colors/shaders.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | 7 | uniform vs_params { 8 | mat4 model; 9 | mat4 view; 10 | mat4 projection; 11 | }; 12 | 13 | void main() { 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | @end 17 | 18 | @fs fs 19 | out vec4 FragColor; 20 | 21 | uniform fs_params { 22 | vec3 objectColor; 23 | vec3 lightColor; 24 | }; 25 | 26 | void main() { 27 | FragColor = vec4(lightColor * objectColor, 1.0); 28 | } 29 | @end 30 | 31 | @fs light_cube_fs 32 | out vec4 FragColor; 33 | 34 | void main() { 35 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 36 | } 37 | @end 38 | 39 | 40 | @program simple vs fs 41 | @program light_cube vs light_cube_fs 42 | -------------------------------------------------------------------------------- /src/2-2-basic-lighting/1-ambient.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | 7 | uniform vs_params { 8 | mat4 model; 9 | mat4 view; 10 | mat4 projection; 11 | }; 12 | 13 | void main() { 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | @end 17 | 18 | @fs fs 19 | out vec4 FragColor; 20 | 21 | uniform fs_params { 22 | vec3 objectColor; 23 | vec3 lightColor; 24 | }; 25 | 26 | void main() { 27 | float ambientStrength = 0.1; 28 | vec3 ambient = ambientStrength * lightColor; 29 | 30 | vec3 result = ambient * objectColor; 31 | FragColor = vec4(result, 1.0); 32 | } 33 | @end 34 | 35 | @fs light_cube_fs 36 | out vec4 FragColor; 37 | 38 | void main() { 39 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 40 | } 41 | @end 42 | 43 | @program ambient vs fs 44 | @program light_cube vs light_cube_fs 45 | -------------------------------------------------------------------------------- /src/2-2-basic-lighting/2-diffuse.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | 8 | out vec3 FragPos; 9 | out vec3 Normal; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | gl_Position = projection * view * model * vec4(aPos, 1.0); 19 | FragPos = vec3(model * vec4(aPos, 1.0)); 20 | // inverse tranpose is left out because: 21 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 22 | // (b) we're not performing non-uniform scale 23 | Normal = mat3(model) * aNormal; 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 FragPos; 29 | in vec3 Normal; 30 | 31 | out vec4 FragColor; 32 | 33 | uniform fs_params { 34 | vec3 objectColor; 35 | vec3 lightColor; 36 | vec3 lightPos; 37 | }; 38 | 39 | void main() { 40 | float ambientStrength = 0.1; 41 | vec3 ambient = ambientStrength * lightColor; 42 | 43 | vec3 norm = normalize(Normal); 44 | vec3 lightDir = normalize(lightPos - FragPos); 45 | float diff = max(dot(norm, lightDir), 0.0); 46 | vec3 diffuse = diff * lightColor; 47 | 48 | vec3 result = (ambient + diffuse) * objectColor; 49 | FragColor = vec4(result, 1.0); 50 | } 51 | @end 52 | 53 | @vs light_cube_vs 54 | in vec3 aPos; 55 | 56 | uniform vs_params { 57 | mat4 model; 58 | mat4 view; 59 | mat4 projection; 60 | }; 61 | 62 | void main() { 63 | gl_Position = projection * view * model * vec4(aPos, 1.0); 64 | } 65 | @end 66 | 67 | @fs light_cube_fs 68 | out vec4 FragColor; 69 | 70 | void main() { 71 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 72 | } 73 | @end 74 | 75 | @program diffuse vs fs 76 | @program light_cube light_cube_vs light_cube_fs 77 | -------------------------------------------------------------------------------- /src/2-2-basic-lighting/3-specular.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | 8 | out vec3 FragPos; 9 | out vec3 Normal; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | gl_Position = projection * view * model * vec4(aPos, 1.0); 19 | FragPos = vec3(model * vec4(aPos, 1.0)); 20 | // inverse tranpose is left out because: 21 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 22 | // (b) we're not performing non-uniform scale 23 | Normal = mat3(model) * aNormal; 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 FragPos; 29 | in vec3 Normal; 30 | 31 | out vec4 FragColor; 32 | 33 | uniform fs_params { 34 | vec3 objectColor; 35 | vec3 viewPos; 36 | vec3 lightColor; 37 | vec3 lightPos; 38 | }; 39 | 40 | void main() { 41 | float ambientStrength = 0.1; 42 | vec3 ambient = ambientStrength * lightColor; 43 | 44 | vec3 norm = normalize(Normal); 45 | vec3 lightDir = normalize(lightPos - FragPos); 46 | float diff = max(dot(norm, lightDir), 0.0); 47 | vec3 diffuse = diff * lightColor; 48 | 49 | float specularStrength = 0.5; 50 | vec3 viewDir = normalize(viewPos - FragPos); 51 | vec3 reflectDir = reflect(-lightDir, norm); 52 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 53 | vec3 specular = specularStrength * spec * lightColor; 54 | 55 | vec3 result = (ambient + diffuse + specular) * objectColor; 56 | FragColor = vec4(result, 1.0); 57 | } 58 | @end 59 | 60 | @vs light_cube_vs 61 | in vec3 aPos; 62 | 63 | uniform vs_params { 64 | mat4 model; 65 | mat4 view; 66 | mat4 projection; 67 | }; 68 | 69 | void main() { 70 | gl_Position = projection * view * model * vec4(aPos, 1.0); 71 | } 72 | @end 73 | 74 | @fs light_cube_fs 75 | out vec4 FragColor; 76 | 77 | void main() { 78 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 79 | } 80 | @end 81 | 82 | @program specular vs fs 83 | @program light_cube light_cube_vs light_cube_fs 84 | -------------------------------------------------------------------------------- /src/2-2-basic-lighting/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(2-2-1-ambient windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-ambient.c) 4 | sokol_shader(1-ambient.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(2-2-2-diffuse windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-diffuse.c) 11 | sokol_shader(2-diffuse.glsl ${slang}) 12 | fips_deps(sokol) 13 | fips_end_app() 14 | 15 | fips_begin_app(2-2-3-specular windowed) 16 | fips_vs_warning_level(3) 17 | fips_files(3-specular.c) 18 | sokol_shader(3-specular.glsl ${slang}) 19 | fips_deps(sokol) 20 | fips_end_app() 21 | -------------------------------------------------------------------------------- /src/2-3-materials/1-material.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | 8 | out vec3 FragPos; 9 | out vec3 Normal; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | gl_Position = projection * view * model * vec4(aPos, 1.0); 19 | FragPos = vec3(model * vec4(aPos, 1.0)); 20 | // inverse tranpose is left out because: 21 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 22 | // (b) we're not performing non-uniform scale 23 | Normal = mat3(model) * aNormal; 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 FragPos; 29 | in vec3 Normal; 30 | 31 | out vec4 FragColor; 32 | 33 | uniform fs_params { 34 | vec3 viewPos; 35 | vec3 lightColor; 36 | vec3 lightPos; 37 | }; 38 | 39 | uniform fs_material { 40 | vec3 ambient; 41 | vec3 diffuse; 42 | vec3 specular; 43 | float shininess; 44 | } material; 45 | 46 | void main() { 47 | // ambient 48 | vec3 ambient = lightColor * material.ambient; 49 | 50 | // diffuse 51 | vec3 norm = normalize(Normal); 52 | vec3 lightDir = normalize(lightPos - FragPos); 53 | float diff = max(dot(norm, lightDir), 0.0); 54 | vec3 diffuse = lightColor * (diff * material.diffuse); 55 | 56 | // specular 57 | vec3 viewDir = normalize(viewPos - FragPos); 58 | vec3 reflectDir = reflect(-lightDir, norm); 59 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 60 | vec3 specular = lightColor * (spec * material.specular); 61 | 62 | vec3 result = ambient + diffuse + specular; 63 | FragColor = vec4(result, 1.0); 64 | } 65 | @end 66 | 67 | @vs light_cube_vs 68 | in vec3 aPos; 69 | 70 | uniform vs_params { 71 | mat4 model; 72 | mat4 view; 73 | mat4 projection; 74 | }; 75 | 76 | void main() { 77 | gl_Position = projection * view * model * vec4(aPos, 1.0); 78 | } 79 | @end 80 | 81 | @fs light_cube_fs 82 | out vec4 FragColor; 83 | 84 | void main() { 85 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 86 | } 87 | @end 88 | 89 | @program phong vs fs 90 | @program light_cube light_cube_vs light_cube_fs 91 | -------------------------------------------------------------------------------- /src/2-3-materials/2-light.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | 8 | out vec3 FragPos; 9 | out vec3 Normal; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | gl_Position = projection * view * model * vec4(aPos, 1.0); 19 | FragPos = vec3(model * vec4(aPos, 1.0)); 20 | // inverse tranpose is left out because: 21 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 22 | // (b) we're not performing non-uniform scale 23 | Normal = mat3(model) * aNormal; 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 FragPos; 29 | in vec3 Normal; 30 | 31 | out vec4 FragColor; 32 | 33 | uniform fs_params { 34 | vec3 viewPos; 35 | }; 36 | 37 | uniform fs_material { 38 | vec3 ambient; 39 | vec3 diffuse; 40 | vec3 specular; 41 | float shininess; 42 | } material; 43 | 44 | uniform fs_light { 45 | vec3 position; 46 | vec3 ambient; 47 | vec3 diffuse; 48 | vec3 specular; 49 | } light; 50 | 51 | void main() { 52 | // ambient 53 | vec3 ambient = light.ambient * material.ambient; 54 | 55 | // diffuse 56 | vec3 norm = normalize(Normal); 57 | vec3 lightDir = normalize(light.position - FragPos); 58 | float diff = max(dot(norm, lightDir), 0.0); 59 | vec3 diffuse = light.diffuse * (diff * material.diffuse); 60 | 61 | // specular 62 | vec3 viewDir = normalize(viewPos - FragPos); 63 | vec3 reflectDir = reflect(-lightDir, norm); 64 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 65 | vec3 specular = light.specular * (spec * material.specular); 66 | 67 | vec3 result = ambient + diffuse + specular; 68 | FragColor = vec4(result, 1.0); 69 | } 70 | @end 71 | 72 | @vs light_cube_vs 73 | in vec3 aPos; 74 | 75 | uniform vs_params { 76 | mat4 model; 77 | mat4 view; 78 | mat4 projection; 79 | }; 80 | 81 | void main() { 82 | gl_Position = projection * view * model * vec4(aPos, 1.0); 83 | } 84 | @end 85 | 86 | @fs light_cube_fs 87 | out vec4 FragColor; 88 | 89 | void main() { 90 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 91 | } 92 | @end 93 | 94 | @program phong vs fs 95 | @program light_cube light_cube_vs light_cube_fs 96 | -------------------------------------------------------------------------------- /src/2-3-materials/3-light-colors.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | 8 | out vec3 FragPos; 9 | out vec3 Normal; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | gl_Position = projection * view * model * vec4(aPos, 1.0); 19 | FragPos = vec3(model * vec4(aPos, 1.0)); 20 | // inverse tranpose is left out because: 21 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 22 | // (b) we're not performing non-uniform scale 23 | Normal = mat3(model) * aNormal; 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 FragPos; 29 | in vec3 Normal; 30 | 31 | out vec4 FragColor; 32 | 33 | uniform fs_params { 34 | vec3 viewPos; 35 | }; 36 | 37 | uniform fs_material { 38 | vec3 ambient; 39 | vec3 diffuse; 40 | vec3 specular; 41 | float shininess; 42 | } material; 43 | 44 | uniform fs_light { 45 | vec3 position; 46 | vec3 ambient; 47 | vec3 diffuse; 48 | vec3 specular; 49 | } light; 50 | 51 | void main() { 52 | // ambient 53 | vec3 ambient = light.ambient * material.ambient; 54 | 55 | // diffuse 56 | vec3 norm = normalize(Normal); 57 | vec3 lightDir = normalize(light.position - FragPos); 58 | float diff = max(dot(norm, lightDir), 0.0); 59 | vec3 diffuse = light.diffuse * (diff * material.diffuse); 60 | 61 | // specular 62 | vec3 viewDir = normalize(viewPos - FragPos); 63 | vec3 reflectDir = reflect(-lightDir, norm); 64 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 65 | vec3 specular = light.specular * (spec * material.specular); 66 | 67 | vec3 result = ambient + diffuse + specular; 68 | FragColor = vec4(result, 1.0); 69 | } 70 | @end 71 | 72 | @vs light_cube_vs 73 | in vec3 aPos; 74 | 75 | uniform vs_params { 76 | mat4 model; 77 | mat4 view; 78 | mat4 projection; 79 | }; 80 | 81 | void main() { 82 | gl_Position = projection * view * model * vec4(aPos, 1.0); 83 | } 84 | @end 85 | 86 | @fs light_cube_fs 87 | out vec4 FragColor; 88 | 89 | void main() { 90 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 91 | } 92 | @end 93 | 94 | @program phong vs fs 95 | @program light_cube light_cube_vs light_cube_fs 96 | -------------------------------------------------------------------------------- /src/2-3-materials/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(2-3-1-material windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-material.c) 4 | sokol_shader(1-material.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(2-3-2-light windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-light.c) 11 | sokol_shader(2-light.glsl ${slang}) 12 | fips_deps(sokol) 13 | fips_end_app() 14 | 15 | fips_begin_app(2-3-3-light-colors windowed) 16 | fips_vs_warning_level(3) 17 | fips_files(3-light-colors.c) 18 | sokol_shader(3-light-colors.glsl ${slang}) 19 | fips_deps(sokol) 20 | fips_end_app() 21 | -------------------------------------------------------------------------------- /src/2-4-lighting-maps/1-diffuse-map.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | in vec2 aTexCoords; 8 | 9 | out vec3 FragPos; 10 | out vec3 Normal; 11 | out vec2 TexCoords; 12 | 13 | uniform vs_params { 14 | mat4 model; 15 | mat4 view; 16 | mat4 projection; 17 | }; 18 | 19 | void main() { 20 | gl_Position = projection * view * model * vec4(aPos, 1.0); 21 | FragPos = vec3(model * vec4(aPos, 1.0)); 22 | // inverse tranpose is left out because: 23 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 24 | // (b) we're not performing non-uniform scale 25 | Normal = mat3(model) * aNormal; 26 | TexCoords = aTexCoords; 27 | } 28 | @end 29 | 30 | @fs fs 31 | in vec3 FragPos; 32 | in vec3 Normal; 33 | in vec2 TexCoords; 34 | 35 | out vec4 FragColor; 36 | 37 | uniform fs_params { 38 | vec3 viewPos; 39 | }; 40 | 41 | uniform fs_material { 42 | vec3 specular; 43 | float shininess; 44 | } material; 45 | 46 | uniform fs_light { 47 | vec3 position; 48 | vec3 ambient; 49 | vec3 diffuse; 50 | vec3 specular; 51 | } light; 52 | 53 | uniform sampler2D diffuse_texture; 54 | 55 | void main() { 56 | // ambient 57 | vec3 ambient = light.ambient * vec3(texture(diffuse_texture, TexCoords)); 58 | 59 | // diffuse 60 | vec3 norm = normalize(Normal); 61 | vec3 lightDir = normalize(light.position - FragPos); 62 | float diff = max(dot(norm, lightDir), 0.0); 63 | vec3 diffuse = light.diffuse * diff * vec3(texture(diffuse_texture, TexCoords)); 64 | 65 | // specular 66 | vec3 viewDir = normalize(viewPos - FragPos); 67 | vec3 reflectDir = reflect(-lightDir, norm); 68 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 69 | vec3 specular = light.specular * (spec * material.specular); 70 | 71 | vec3 result = ambient + diffuse + specular; 72 | FragColor = vec4(result, 1.0); 73 | } 74 | @end 75 | 76 | @vs light_cube_vs 77 | in vec3 aPos; 78 | 79 | uniform vs_params { 80 | mat4 model; 81 | mat4 view; 82 | mat4 projection; 83 | }; 84 | 85 | void main() { 86 | gl_Position = projection * view * model * vec4(aPos, 1.0); 87 | } 88 | @end 89 | 90 | @fs light_cube_fs 91 | out vec4 FragColor; 92 | 93 | void main() { 94 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 95 | } 96 | @end 97 | 98 | @program phong vs fs 99 | @program light_cube light_cube_vs light_cube_fs 100 | -------------------------------------------------------------------------------- /src/2-4-lighting-maps/2-specular-map.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | in vec2 aTexCoords; 8 | 9 | out vec3 FragPos; 10 | out vec3 Normal; 11 | out vec2 TexCoords; 12 | 13 | uniform vs_params { 14 | mat4 model; 15 | mat4 view; 16 | mat4 projection; 17 | }; 18 | 19 | void main() { 20 | gl_Position = projection * view * model * vec4(aPos, 1.0); 21 | FragPos = vec3(model * vec4(aPos, 1.0)); 22 | // inverse tranpose is left out because: 23 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 24 | // (b) we're not performing non-uniform scale 25 | Normal = mat3(model) * aNormal; 26 | TexCoords = aTexCoords; 27 | } 28 | @end 29 | 30 | @fs fs 31 | in vec3 FragPos; 32 | in vec3 Normal; 33 | in vec2 TexCoords; 34 | 35 | out vec4 FragColor; 36 | 37 | uniform fs_params { 38 | vec3 viewPos; 39 | }; 40 | 41 | uniform fs_material { 42 | float shininess; 43 | } material; 44 | 45 | uniform fs_light { 46 | vec3 position; 47 | vec3 ambient; 48 | vec3 diffuse; 49 | vec3 specular; 50 | } light; 51 | 52 | uniform sampler2D diffuse_texture; 53 | uniform sampler2D specular_texture; 54 | 55 | void main() { 56 | // ambient 57 | vec3 ambient = light.ambient * vec3(texture(diffuse_texture, TexCoords)); 58 | 59 | // diffuse 60 | vec3 norm = normalize(Normal); 61 | vec3 lightDir = normalize(light.position - FragPos); 62 | float diff = max(dot(norm, lightDir), 0.0); 63 | vec3 diffuse = light.diffuse * diff * vec3(texture(diffuse_texture, TexCoords)); 64 | 65 | // specular 66 | vec3 viewDir = normalize(viewPos - FragPos); 67 | vec3 reflectDir = reflect(-lightDir, norm); 68 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 69 | vec3 specular = light.specular * spec * vec3(texture(specular_texture, TexCoords)); 70 | 71 | vec3 result = ambient + diffuse + specular; 72 | FragColor = vec4(result, 1.0); 73 | } 74 | @end 75 | 76 | @vs light_cube_vs 77 | in vec3 aPos; 78 | 79 | uniform vs_params { 80 | mat4 model; 81 | mat4 view; 82 | mat4 projection; 83 | }; 84 | 85 | void main() { 86 | gl_Position = projection * view * model * vec4(aPos, 1.0); 87 | } 88 | @end 89 | 90 | @fs light_cube_fs 91 | out vec4 FragColor; 92 | 93 | void main() { 94 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 95 | } 96 | @end 97 | 98 | @program phong vs fs 99 | @program light_cube light_cube_vs light_cube_fs 100 | -------------------------------------------------------------------------------- /src/2-4-lighting-maps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(2-4-1-diffuse-map windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-diffuse-map.c) 4 | sokol_shader(1-diffuse-map.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(2-4-2-specular-map windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-specular-map.c) 12 | sokol_shader(2-specular-map.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | -------------------------------------------------------------------------------- /src/2-4-lighting-maps/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container2.png 7 | - container2_specular.png 8 | -------------------------------------------------------------------------------- /src/2-5-light-casters/1-directional-light.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | in vec2 aTexCoords; 8 | 9 | out vec3 FragPos; 10 | out vec3 Normal; 11 | out vec2 TexCoords; 12 | 13 | uniform vs_params { 14 | mat4 model; 15 | mat4 view; 16 | mat4 projection; 17 | }; 18 | 19 | void main() { 20 | gl_Position = projection * view * model * vec4(aPos, 1.0); 21 | FragPos = vec3(model * vec4(aPos, 1.0)); 22 | // inverse tranpose is left out because: 23 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 24 | // (b) we're not performing non-uniform scale 25 | Normal = mat3(model) * aNormal; 26 | TexCoords = aTexCoords; 27 | } 28 | @end 29 | 30 | @fs fs 31 | in vec3 FragPos; 32 | in vec3 Normal; 33 | in vec2 TexCoords; 34 | 35 | out vec4 FragColor; 36 | 37 | uniform fs_params { 38 | vec3 viewPos; 39 | }; 40 | 41 | uniform fs_material { 42 | float shininess; 43 | } material; 44 | 45 | uniform fs_light { 46 | vec3 direction; 47 | vec3 ambient; 48 | vec3 diffuse; 49 | vec3 specular; 50 | } light; 51 | 52 | uniform sampler2D diffuse_texture; 53 | uniform sampler2D specular_texture; 54 | 55 | void main() { 56 | // ambient 57 | vec3 ambient = light.ambient * vec3(texture(diffuse_texture, TexCoords)); 58 | 59 | // diffuse 60 | vec3 norm = normalize(Normal); 61 | vec3 lightDir = normalize(-light.direction); 62 | float diff = max(dot(norm, lightDir), 0.0); 63 | vec3 diffuse = light.diffuse * diff * vec3(texture(diffuse_texture, TexCoords)); 64 | 65 | // specular 66 | vec3 viewDir = normalize(viewPos - FragPos); 67 | vec3 reflectDir = reflect(-lightDir, norm); 68 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 69 | vec3 specular = light.specular * spec * vec3(texture(specular_texture, TexCoords)); 70 | 71 | vec3 result = ambient + diffuse + specular; 72 | FragColor = vec4(result, 1.0); 73 | } 74 | @end 75 | 76 | @program phong vs fs 77 | -------------------------------------------------------------------------------- /src/2-5-light-casters/2-point-light.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | in vec2 aTexCoords; 8 | 9 | out vec3 FragPos; 10 | out vec3 Normal; 11 | out vec2 TexCoords; 12 | 13 | uniform vs_params { 14 | mat4 model; 15 | mat4 view; 16 | mat4 projection; 17 | }; 18 | 19 | void main() { 20 | gl_Position = projection * view * model * vec4(aPos, 1.0); 21 | FragPos = vec3(model * vec4(aPos, 1.0)); 22 | // inverse tranpose is left out because: 23 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 24 | // (b) we're not performing non-uniform scale 25 | Normal = mat3(model) * aNormal; 26 | TexCoords = aTexCoords; 27 | } 28 | @end 29 | 30 | @fs fs 31 | in vec3 FragPos; 32 | in vec3 Normal; 33 | in vec2 TexCoords; 34 | 35 | out vec4 FragColor; 36 | 37 | uniform fs_params { 38 | vec3 viewPos; 39 | }; 40 | 41 | uniform fs_material { 42 | float shininess; 43 | } material; 44 | 45 | uniform sampler2D diffuse_texture; 46 | uniform sampler2D specular_texture; 47 | 48 | uniform fs_light { 49 | vec3 position; 50 | 51 | vec3 ambient; 52 | vec3 diffuse; 53 | vec3 specular; 54 | 55 | float constant; 56 | float linear; 57 | float quadratic; 58 | } light; 59 | 60 | void main() { 61 | // ambient 62 | vec3 ambient = light.ambient * vec3(texture(diffuse_texture, TexCoords)); 63 | 64 | // diffuse 65 | vec3 norm = normalize(Normal); 66 | vec3 lightDir = normalize(light.position - FragPos); 67 | float diff = max(dot(norm, lightDir), 0.0); 68 | vec3 diffuse = light.diffuse * diff * vec3(texture(diffuse_texture, TexCoords)); 69 | 70 | // specular 71 | vec3 viewDir = normalize(viewPos - FragPos); 72 | vec3 reflectDir = reflect(-lightDir, norm); 73 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 74 | vec3 specular = light.specular * spec * vec3(texture(specular_texture, TexCoords)); 75 | 76 | // attenuation 77 | float distance = length(light.position - FragPos); 78 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 79 | 80 | ambient *= attenuation; 81 | diffuse *= attenuation; 82 | specular *= attenuation; 83 | 84 | vec3 result = ambient + diffuse + specular; 85 | FragColor = vec4(result, 1.0); 86 | } 87 | @end 88 | 89 | @vs light_cube_vs 90 | in vec3 aPos; 91 | 92 | uniform vs_params { 93 | mat4 model; 94 | mat4 view; 95 | mat4 projection; 96 | }; 97 | 98 | void main() { 99 | gl_Position = projection * view * model * vec4(aPos, 1.0); 100 | } 101 | @end 102 | 103 | @fs light_cube_fs 104 | out vec4 FragColor; 105 | 106 | void main() { 107 | FragColor = vec4(1.0); // set all 4 vector values to 1.0 108 | } 109 | @end 110 | 111 | @program phong vs fs 112 | @program light_cube light_cube_vs light_cube_fs 113 | -------------------------------------------------------------------------------- /src/2-5-light-casters/3-spot-light.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | in vec2 aTexCoords; 8 | 9 | out vec3 FragPos; 10 | out vec3 Normal; 11 | out vec2 TexCoords; 12 | 13 | uniform vs_params { 14 | mat4 model; 15 | mat4 view; 16 | mat4 projection; 17 | }; 18 | 19 | void main() { 20 | gl_Position = projection * view * model * vec4(aPos, 1.0); 21 | FragPos = vec3(model * vec4(aPos, 1.0)); 22 | // inverse tranpose is left out because: 23 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 24 | // (b) we're not performing non-uniform scale 25 | Normal = mat3(model) * aNormal; 26 | TexCoords = aTexCoords; 27 | } 28 | @end 29 | 30 | @fs fs 31 | in vec3 FragPos; 32 | in vec3 Normal; 33 | in vec2 TexCoords; 34 | 35 | out vec4 FragColor; 36 | 37 | uniform fs_params { 38 | vec3 viewPos; 39 | }; 40 | 41 | uniform fs_material { 42 | float shininess; 43 | } material; 44 | 45 | uniform fs_light { 46 | vec3 position; 47 | vec3 direction; 48 | float cut_off; 49 | 50 | vec3 ambient; 51 | vec3 diffuse; 52 | vec3 specular; 53 | 54 | float constant; 55 | float linear; 56 | float quadratic; 57 | } light; 58 | 59 | uniform sampler2D diffuse_texture; 60 | uniform sampler2D specular_texture; 61 | 62 | void main() { 63 | // attenuation 64 | float distance = length(light.position - FragPos); 65 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 66 | 67 | // ambient 68 | vec3 ambient = light.ambient * vec3(texture(diffuse_texture, TexCoords)); 69 | ambient *= attenuation; 70 | 71 | vec3 lightDir = normalize(light.position - FragPos); 72 | 73 | // check if lighting is inside the spotlight cone 74 | float theta = dot(lightDir, normalize(-light.direction)); 75 | 76 | if(theta > light.cut_off) // remember that we're working with angles as cosines instead of degrees so a '>' is used. 77 | { 78 | // diffuse 79 | vec3 norm = normalize(Normal); 80 | float diff = max(dot(norm, lightDir), 0.0); 81 | vec3 diffuse = light.diffuse * diff * vec3(texture(diffuse_texture, TexCoords)); 82 | 83 | // specular 84 | vec3 viewDir = normalize(viewPos - FragPos); 85 | vec3 reflectDir = reflect(-lightDir, norm); 86 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 87 | vec3 specular = light.specular * spec * vec3(texture(specular_texture, TexCoords)); 88 | 89 | diffuse *= attenuation; 90 | specular *= attenuation; 91 | 92 | vec3 result = ambient + diffuse + specular; 93 | FragColor = vec4(result, 1.0); 94 | } 95 | else 96 | { 97 | // else, use ambient light so scene isn't completely dark outside the spotlight. 98 | FragColor = vec4(ambient, 1.0); 99 | } 100 | } 101 | @end 102 | 103 | @program phong vs fs 104 | -------------------------------------------------------------------------------- /src/2-5-light-casters/4-soft-spot-light.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec3 aNormal; 7 | in vec2 aTexCoords; 8 | 9 | out vec3 FragPos; 10 | out vec3 Normal; 11 | out vec2 TexCoords; 12 | 13 | uniform vs_params { 14 | mat4 model; 15 | mat4 view; 16 | mat4 projection; 17 | }; 18 | 19 | void main() { 20 | gl_Position = projection * view * model * vec4(aPos, 1.0); 21 | FragPos = vec3(model * vec4(aPos, 1.0)); 22 | // inverse tranpose is left out because: 23 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 24 | // (b) we're not performing non-uniform scale 25 | Normal = mat3(model) * aNormal; 26 | TexCoords = aTexCoords; 27 | } 28 | @end 29 | 30 | @fs fs 31 | in vec3 FragPos; 32 | in vec3 Normal; 33 | in vec2 TexCoords; 34 | 35 | out vec4 FragColor; 36 | 37 | uniform fs_params { 38 | vec3 viewPos; 39 | }; 40 | 41 | uniform fs_material { 42 | float shininess; 43 | } material; 44 | 45 | uniform fs_light { 46 | vec3 position; 47 | vec3 direction; 48 | float cut_off; 49 | float outer_cut_off; 50 | 51 | vec3 ambient; 52 | vec3 diffuse; 53 | vec3 specular; 54 | 55 | float constant; 56 | float linear; 57 | float quadratic; 58 | } light; 59 | 60 | uniform sampler2D diffuse_texture; 61 | uniform sampler2D specular_texture; 62 | 63 | void main() { 64 | // ambient 65 | vec3 ambient = light.ambient * vec3(texture(diffuse_texture, TexCoords)); 66 | 67 | // diffuse 68 | vec3 norm = normalize(Normal); 69 | vec3 lightDir = normalize(light.position - FragPos); 70 | float diff = max(dot(norm, lightDir), 0.0); 71 | vec3 diffuse = light.diffuse * diff * vec3(texture(diffuse_texture, TexCoords)); 72 | 73 | // specular 74 | vec3 viewDir = normalize(viewPos - FragPos); 75 | vec3 reflectDir = reflect(-lightDir, norm); 76 | float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); 77 | vec3 specular = light.specular * spec * vec3(texture(specular_texture, TexCoords)); 78 | 79 | // attenuation 80 | float distance = length(light.position - FragPos); 81 | float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); 82 | 83 | ambient *= attenuation; 84 | diffuse *= attenuation; 85 | specular *= attenuation; 86 | 87 | // check if lighting is inside the spotlight cone 88 | float theta = dot(lightDir, normalize(-light.direction)); 89 | float epsilon = light.cut_off - light.outer_cut_off; 90 | float intensity = clamp((theta - light.outer_cut_off) / epsilon, 0.0, 1.0); 91 | 92 | diffuse *= intensity; 93 | specular *= intensity; 94 | 95 | vec3 result = ambient + diffuse + specular; 96 | FragColor = vec4(result, 1.0); 97 | } 98 | @end 99 | 100 | @program phong vs fs 101 | -------------------------------------------------------------------------------- /src/2-5-light-casters/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(2-5-1-directional-light windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-directional-light.c) 4 | sokol_shader(1-directional-light.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(2-5-2-point-light windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-point-light.c) 12 | sokol_shader(2-point-light.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(2-5-3-spot-light windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-spot-light.c) 20 | sokol_shader(3-spot-light.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | 25 | fips_begin_app(2-5-4-soft-spot-light windowed) 26 | fips_vs_warning_level(3) 27 | fips_files(4-soft-spot-light.c) 28 | sokol_shader(4-soft-spot-light.glsl ${slang}) 29 | fipsutil_copy(textures-assets.yml) 30 | fips_deps(sokol) 31 | fips_end_app() 32 | -------------------------------------------------------------------------------- /src/2-5-light-casters/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container2.png 7 | - container2_specular.png 8 | -------------------------------------------------------------------------------- /src/2-6-multiple-lights/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(2-6-1-combined-lights windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-combined-lights.c) 4 | sokol_shader(1-combined-lights.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | -------------------------------------------------------------------------------- /src/2-6-multiple-lights/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container2.png 7 | - container2_specular.png 8 | -------------------------------------------------------------------------------- /src/3-1-model/1-backpack-diffuse.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @program phong vs fs 35 | -------------------------------------------------------------------------------- /src/3-1-model/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(3-1-1-backpack-diffuse windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-backpack-diffuse.c) 4 | sokol_shader(1-backpack-diffuse.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(3-1-2-backpack-lights windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-backpack-lights.c) 12 | sokol_shader(2-backpack-lights.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | -------------------------------------------------------------------------------- /src/3-1-model/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - backpack.mtl 7 | - backpack.obj 8 | - backpack_diffuse.jpg 9 | - backpack_specular.jpg 10 | -------------------------------------------------------------------------------- /src/4-1-depth-testing/1-depth-always.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @program phong vs fs 35 | -------------------------------------------------------------------------------- /src/4-1-depth-testing/2-depth-less.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @program phong vs fs 35 | -------------------------------------------------------------------------------- /src/4-1-depth-testing/3-depth-buffer.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | void main() { 28 | frag_color = vec4(vec3(gl_FragCoord.z), 1.0); 29 | } 30 | @end 31 | 32 | @program phong vs fs 33 | -------------------------------------------------------------------------------- /src/4-1-depth-testing/4-linear-depth-buffer.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | float near = 0.1; 28 | float far = 100.0; 29 | 30 | float linearize_depth(float depth) 31 | { 32 | float z = depth * 2.0 - 1.0; // back to NDC 33 | return (2.0 * near * far) / (far + near - z * (far - near)); 34 | } 35 | 36 | void main() 37 | { 38 | float depth = linearize_depth(gl_FragCoord.z) / far; // divide by far for demonstration 39 | frag_color = vec4(vec3(depth), 1.0); 40 | } 41 | @end 42 | 43 | @program phong vs fs 44 | -------------------------------------------------------------------------------- /src/4-1-depth-testing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-1-1-depth-always windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-depth-always.c) 4 | sokol_shader(1-depth-always.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(4-1-2-depth-less windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-depth-less.c) 12 | sokol_shader(2-depth-less.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(4-1-3-depth-buffer windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-depth-buffer.c) 20 | sokol_shader(3-depth-buffer.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | 25 | fips_begin_app(4-1-4-linear-depth-buffer windowed) 26 | fips_vs_warning_level(3) 27 | fips_files(4-linear-depth-buffer.c) 28 | sokol_shader(4-linear-depth-buffer.glsl ${slang}) 29 | fipsutil_copy(textures-assets.yml) 30 | fips_deps(sokol) 31 | fips_end_app() 32 | -------------------------------------------------------------------------------- /src/4-1-depth-testing/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - marble.jpg 7 | - metal.png 8 | -------------------------------------------------------------------------------- /src/4-10-instancing/1-instancing.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Instancing (1) 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #include "../libs/hmm/HandmadeMath.h" 8 | #include "1-instancing.glsl.h" 9 | #define LOPGL_APP_IMPL 10 | #include "../lopgl_app.h" 11 | #include "string.h" 12 | 13 | /* application state */ 14 | static struct { 15 | sg_pipeline pip; 16 | sg_bindings bind; 17 | sg_pass_action pass_action; 18 | hmm_vec4 translations[100]; // using arrays vec4 to avoid alignment issues with cross shader compilation 19 | } state; 20 | 21 | static void init(void) { 22 | lopgl_setup(); 23 | 24 | if (sapp_gles2()) { 25 | /* this demo needs GLES3/WebGL because we are using gl_InstanceID in the shader */ 26 | return; 27 | } 28 | 29 | /* create shader from code-generated sg_shader_desc */ 30 | sg_shader shd = sg_make_shader(simple_shader_desc()); 31 | 32 | float vertices[] = { 33 | // positions // colors 34 | -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 35 | 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, 36 | -0.05f, -0.05f, 0.0f, 0.0f, 1.0f, 37 | 38 | -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 39 | 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, 40 | 0.05f, 0.05f, 0.0f, 1.0f, 1.0f 41 | }; 42 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 43 | .size = sizeof(vertices), 44 | .content = vertices, 45 | .label = "quad-vertices" 46 | }); 47 | 48 | /* a pipeline state object */ 49 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 50 | .shader = shd, 51 | .layout = { 52 | .attrs = { 53 | [ATTR_vs_aPos].format = SG_VERTEXFORMAT_FLOAT2, 54 | [ATTR_vs_aColor].format = SG_VERTEXFORMAT_FLOAT3 55 | } 56 | }, 57 | .label = "quad-pipeline" 58 | }); 59 | 60 | /* a pass action to clear framebuffer */ 61 | state.pass_action = (sg_pass_action) { 62 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.1f, 0.1f, 0.1f, 1.0f} } 63 | }; 64 | 65 | int index = 0; 66 | float offset = 0.1f; 67 | for(int y = -10; y < 10; y += 2) { 68 | for(int x = -10; x < 10; x += 2) { 69 | float x_pos = (float)x / 10.0f + offset; 70 | float y_pos = (float)y / 10.0f + offset; 71 | state.translations[index++] = HMM_Vec4(x_pos, y_pos, 0.0, 0.0); 72 | } 73 | } 74 | } 75 | 76 | void frame(void) { 77 | /* can't do anything useful on GLES2/WebGL */ 78 | if (sapp_gles2()) { 79 | lopgl_render_gles2_fallback(); 80 | return; 81 | } 82 | 83 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 84 | sg_apply_pipeline(state.pip); 85 | sg_apply_bindings(&state.bind); 86 | 87 | vs_params_t vs_params; 88 | memcpy(vs_params.offsets, state.translations, sizeof(vs_params.offsets)); 89 | 90 | sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, &vs_params, sizeof(vs_params)); 91 | 92 | sg_draw(0, 6, 100); 93 | sg_end_pass(); 94 | sg_commit(); 95 | } 96 | 97 | void cleanup(void) { 98 | sg_shutdown(); 99 | } 100 | 101 | void event(const sapp_event* e) { 102 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 103 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 104 | sapp_request_quit(); 105 | } 106 | } 107 | } 108 | 109 | sapp_desc sokol_main(int argc, char* argv[]) { 110 | return (sapp_desc){ 111 | .init_cb = init, 112 | .frame_cb = frame, 113 | .cleanup_cb = cleanup, 114 | .event_cb = event, 115 | .width = 800, 116 | .height = 600, 117 | .window_title = "Instancing (LearnOpenGL)", 118 | }; 119 | } 120 | -------------------------------------------------------------------------------- /src/4-10-instancing/1-instancing.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec4 hmm_vec4 2 | 3 | @vs vs 4 | in vec2 aPos; 5 | in vec3 aColor; 6 | out vec3 fColor; 7 | 8 | uniform vs_params { 9 | // using arrays vec4 to avoid alignment issues with cross shader compilation 10 | vec4 offsets[100]; 11 | }; 12 | 13 | void main() { 14 | vec2 offset = offsets[gl_InstanceID].xy; 15 | gl_Position = vec4(aPos + offset, 0.0, 1.0); 16 | fColor = aColor; 17 | } 18 | @end 19 | 20 | @fs fs 21 | in vec3 fColor; 22 | out vec4 FragColor; 23 | 24 | void main() { 25 | FragColor = vec4(fColor, 1.0); 26 | } 27 | @end 28 | 29 | @program simple vs fs 30 | -------------------------------------------------------------------------------- /src/4-10-instancing/2-instanced-arrays.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Instancing (2) 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #include "../libs/hmm/HandmadeMath.h" 8 | #include "2-instanced-arrays.glsl.h" 9 | #define LOPGL_APP_IMPL 10 | #include "../lopgl_app.h" 11 | #include "string.h" 12 | 13 | /* application state */ 14 | static struct { 15 | sg_pipeline pip; 16 | sg_bindings bind; 17 | sg_pass_action pass_action; 18 | } state; 19 | 20 | static void init(void) { 21 | lopgl_setup(); 22 | 23 | if (sapp_gles2()) { 24 | /* this demo needs GLES3/WebGL because we are using gl_InstanceID in the shader */ 25 | return; 26 | } 27 | 28 | /* create shader from code-generated sg_shader_desc */ 29 | sg_shader shd = sg_make_shader(simple_shader_desc()); 30 | 31 | float vertices[] = { 32 | // positions // colors 33 | -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 34 | 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, 35 | -0.05f, -0.05f, 0.0f, 0.0f, 1.0f, 36 | 37 | -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, 38 | 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, 39 | 0.05f, 0.05f, 0.0f, 1.0f, 1.0f 40 | }; 41 | 42 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 43 | .size = sizeof(vertices), 44 | .content = vertices, 45 | .label = "quad-vertices" 46 | }); 47 | 48 | hmm_vec2 translations[100]; 49 | int index = 0; 50 | float offset = 0.1f; 51 | for(int y = -10; y < 10; y += 2) { 52 | for(int x = -10; x < 10; x += 2) { 53 | float x_pos = (float)x / 10.0f + offset; 54 | float y_pos = (float)y / 10.0f + offset; 55 | translations[index++] = HMM_Vec2(x_pos, y_pos); 56 | } 57 | } 58 | 59 | state.bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){ 60 | .size = sizeof(translations), 61 | .content = translations, 62 | .label = "offsets" 63 | }); 64 | 65 | /* a pipeline state object */ 66 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 67 | .shader = shd, 68 | .layout = { 69 | /* vertex buffer at slot 1 must step per instance */ 70 | .buffers[1].step_func = SG_VERTEXSTEP_PER_INSTANCE, 71 | .attrs = { 72 | [ATTR_vs_aPos] = { .format=SG_VERTEXFORMAT_FLOAT2, .buffer_index=0 }, 73 | [ATTR_vs_aColor] = { .format=SG_VERTEXFORMAT_FLOAT3, .buffer_index=0 }, 74 | [ATTR_vs_aOffset] = { .format=SG_VERTEXFORMAT_FLOAT2, .buffer_index=1 } 75 | } 76 | }, 77 | .label = "quad-pipeline" 78 | }); 79 | 80 | /* a pass action to clear framebuffer */ 81 | state.pass_action = (sg_pass_action) { 82 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.1f, 0.1f, 0.1f, 1.0f} } 83 | }; 84 | } 85 | 86 | void frame(void) { 87 | /* can't do anything useful on GLES2/WebGL */ 88 | if (sapp_gles2()) { 89 | lopgl_render_gles2_fallback(); 90 | return; 91 | } 92 | 93 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 94 | sg_apply_pipeline(state.pip); 95 | sg_apply_bindings(&state.bind); 96 | sg_draw(0, 6, 100); 97 | sg_end_pass(); 98 | sg_commit(); 99 | } 100 | 101 | void cleanup(void) { 102 | sg_shutdown(); 103 | } 104 | 105 | void event(const sapp_event* e) { 106 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 107 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 108 | sapp_request_quit(); 109 | } 110 | } 111 | } 112 | 113 | sapp_desc sokol_main(int argc, char* argv[]) { 114 | return (sapp_desc){ 115 | .init_cb = init, 116 | .frame_cb = frame, 117 | .cleanup_cb = cleanup, 118 | .event_cb = event, 119 | .width = 800, 120 | .height = 600, 121 | .window_title = "Instanced Arrays (LearnOpenGL)", 122 | }; 123 | } 124 | -------------------------------------------------------------------------------- /src/4-10-instancing/2-instanced-arrays.glsl: -------------------------------------------------------------------------------- 1 | @vs vs 2 | in vec2 aPos; 3 | in vec3 aColor; 4 | in vec2 aOffset; 5 | out vec3 fColor; 6 | 7 | void main() { 8 | vec2 pos = aPos * (gl_InstanceID / 100.0); 9 | gl_Position = vec4(pos + aOffset, 0.0, 1.0); 10 | fColor = aColor; 11 | } 12 | @end 13 | 14 | @fs fs 15 | in vec3 fColor; 16 | out vec4 FragColor; 17 | 18 | void main() { 19 | FragColor = vec4(fColor, 1.0); 20 | } 21 | @end 22 | 23 | @program simple vs fs 24 | -------------------------------------------------------------------------------- /src/4-10-instancing/3-asteroid-field.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @program phong vs fs 35 | -------------------------------------------------------------------------------- /src/4-10-instancing/4-asteroid-field-instanced.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs_planet 4 | in vec3 a_pos; 5 | in vec2 a_tex_coords; 6 | out vec2 tex_coords; 7 | 8 | uniform vs_params_planet { 9 | mat4 model; 10 | mat4 view; 11 | mat4 projection; 12 | }; 13 | 14 | void main() { 15 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 16 | tex_coords = a_tex_coords; 17 | } 18 | @end 19 | 20 | @vs vs_rock 21 | in vec3 a_pos; 22 | in vec2 a_tex_coords; 23 | in vec4 instance_mat0; 24 | in vec4 instance_mat1; 25 | in vec4 instance_mat2; 26 | in vec4 instance_mat3; 27 | out vec2 tex_coords; 28 | 29 | uniform vs_params_rock { 30 | mat4 view; 31 | mat4 projection; 32 | }; 33 | 34 | void main() { 35 | mat4 instance_matrix = mat4(instance_mat0, instance_mat1, instance_mat2, instance_mat3); 36 | gl_Position = projection * view * instance_matrix * vec4(a_pos, 1.0); 37 | tex_coords = a_tex_coords; 38 | } 39 | @end 40 | 41 | @fs fs 42 | in vec2 tex_coords; 43 | out vec4 frag_color; 44 | 45 | uniform sampler2D diffuse_texture; 46 | 47 | void main() { 48 | frag_color = texture(diffuse_texture, tex_coords); 49 | } 50 | @end 51 | 52 | @program planet vs_planet fs 53 | @program rock vs_rock fs 54 | -------------------------------------------------------------------------------- /src/4-10-instancing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-10-1-instancing windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-instancing.c) 4 | sokol_shader(1-instancing.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(4-10-2-instanced-arrays windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-instanced-arrays.c) 11 | sokol_shader(2-instanced-arrays.glsl ${slang}) 12 | fips_deps(sokol) 13 | fips_end_app() 14 | 15 | fips_begin_app(4-10-3-asteroid-field windowed) 16 | fips_vs_warning_level(3) 17 | fips_files(3-asteroid-field.c) 18 | sokol_shader(3-asteroid-field.glsl ${slang}) 19 | fipsutil_copy(textures-assets.yml) 20 | fips_deps(sokol) 21 | fips_end_app() 22 | 23 | fips_begin_app(4-10-4-asteroid-field-instanced windowed) 24 | fips_vs_warning_level(3) 25 | fips_files(4-asteroid-field-instanced.c) 26 | sokol_shader(4-asteroid-field-instanced.glsl ${slang}) 27 | fipsutil_copy(textures-assets.yml) 28 | fips_deps(sokol) 29 | fips_end_app() 30 | -------------------------------------------------------------------------------- /src/4-10-instancing/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - planet.mtl 7 | - planet.obj 8 | - mars.png 9 | - rock.mtl 10 | - rock.obj 11 | - rock.png 12 | -------------------------------------------------------------------------------- /src/4-11-anti-aliasing/1-msaa.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Anti Aliasing (1) 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "hmm/HandmadeMath.h" 7 | #include "1-msaa.glsl.h" 8 | #define LOPGL_APP_IMPL 9 | #include "../lopgl_app.h" 10 | 11 | /* application state */ 12 | static struct { 13 | sg_pipeline pip; 14 | sg_bindings bind; 15 | sg_pass_action pass_action; 16 | } state; 17 | 18 | static void init(void) { 19 | lopgl_setup(); 20 | 21 | float vertices[] = { 22 | -0.5f, -0.5f, -0.5f, 23 | 0.5f, -0.5f, -0.5f, 24 | 0.5f, 0.5f, -0.5f, 25 | 0.5f, 0.5f, -0.5f, 26 | -0.5f, 0.5f, -0.5f, 27 | -0.5f, -0.5f, -0.5f, 28 | 29 | -0.5f, -0.5f, 0.5f, 30 | 0.5f, -0.5f, 0.5f, 31 | 0.5f, 0.5f, 0.5f, 32 | 0.5f, 0.5f, 0.5f, 33 | -0.5f, 0.5f, 0.5f, 34 | -0.5f, -0.5f, 0.5f, 35 | 36 | -0.5f, 0.5f, 0.5f, 37 | -0.5f, 0.5f, -0.5f, 38 | -0.5f, -0.5f, -0.5f, 39 | -0.5f, -0.5f, -0.5f, 40 | -0.5f, -0.5f, 0.5f, 41 | -0.5f, 0.5f, 0.5f, 42 | 43 | 0.5f, 0.5f, 0.5f, 44 | 0.5f, 0.5f, -0.5f, 45 | 0.5f, -0.5f, -0.5f, 46 | 0.5f, -0.5f, -0.5f, 47 | 0.5f, -0.5f, 0.5f, 48 | 0.5f, 0.5f, 0.5f, 49 | 50 | -0.5f, -0.5f, -0.5f, 51 | 0.5f, -0.5f, -0.5f, 52 | 0.5f, -0.5f, 0.5f, 53 | 0.5f, -0.5f, 0.5f, 54 | -0.5f, -0.5f, 0.5f, 55 | -0.5f, -0.5f, -0.5f, 56 | 57 | -0.5f, 0.5f, -0.5f, 58 | 0.5f, 0.5f, -0.5f, 59 | 0.5f, 0.5f, 0.5f, 60 | 0.5f, 0.5f, 0.5f, 61 | -0.5f, 0.5f, 0.5f, 62 | -0.5f, 0.5f, -0.5f 63 | }; 64 | 65 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 66 | .size = sizeof(vertices), 67 | .content = vertices, 68 | .label = "vertices-cube" 69 | }); 70 | 71 | /* create shader from code-generated sg_shader_desc */ 72 | sg_shader shd = sg_make_shader(simple_shader_desc()); 73 | 74 | /* create a pipeline object */ 75 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 76 | .shader = shd, 77 | /* if the vertex layout doesn't have gaps, don't need to provide strides and offsets */ 78 | .layout = { 79 | .attrs = { 80 | [ATTR_vs_aPos].format = SG_VERTEXFORMAT_FLOAT3, 81 | } 82 | }, 83 | .label = "cube-pipeline" 84 | }); 85 | 86 | /* a pass action to clear framebuffer */ 87 | state.pass_action = (sg_pass_action) { 88 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.1f, 0.1f, 0.1f, 1.0f} } 89 | }; 90 | } 91 | 92 | void frame(void) { 93 | lopgl_update(); 94 | 95 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 96 | 97 | sg_apply_pipeline(state.pip); 98 | sg_apply_bindings(&state.bind); 99 | 100 | hmm_mat4 view = lopgl_view_matrix(); 101 | hmm_mat4 projection = HMM_Perspective(lopgl_fov(), (float)sapp_width() / (float)sapp_height(), 0.1f, 100.0f); 102 | 103 | vs_params_t vs_params = { 104 | .model = HMM_Mat4d(1.f), 105 | .view = view, 106 | .projection = projection 107 | }; 108 | 109 | sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, &vs_params, sizeof(vs_params)); 110 | 111 | sg_draw(0, 36, 1); 112 | 113 | lopgl_render_help(); 114 | 115 | sg_end_pass(); 116 | sg_commit(); 117 | } 118 | 119 | void event(const sapp_event* e) { 120 | lopgl_handle_input(e); 121 | } 122 | 123 | 124 | void cleanup(void) { 125 | lopgl_shutdown(); 126 | } 127 | 128 | sapp_desc sokol_main(int argc, char* argv[]) { 129 | return (sapp_desc){ 130 | .init_cb = init, 131 | .frame_cb = frame, 132 | .cleanup_cb = cleanup, 133 | .event_cb = event, 134 | .width = 800, 135 | .height = 600, 136 | .sample_count = 4, 137 | .gl_force_gles2 = true, 138 | .window_title = "MSAA (LearnOpenGL)", 139 | }; 140 | } 141 | -------------------------------------------------------------------------------- /src/4-11-anti-aliasing/1-msaa.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs 4 | in vec3 aPos; 5 | 6 | uniform vs_params { 7 | mat4 model; 8 | mat4 view; 9 | mat4 projection; 10 | }; 11 | 12 | void main() { 13 | gl_Position = projection * view * model * vec4(aPos, 1.0); 14 | } 15 | @end 16 | 17 | @fs fs 18 | out vec4 FragColor; 19 | 20 | void main() { 21 | FragColor = vec4(0.0, 1.0, 0.0, 1.0); 22 | } 23 | @end 24 | 25 | @program simple vs fs 26 | -------------------------------------------------------------------------------- /src/4-11-anti-aliasing/2-offscreen-msaa.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs_offscreen 4 | in vec3 a_pos; 5 | 6 | uniform vs_params { 7 | mat4 model; 8 | mat4 view; 9 | mat4 projection; 10 | }; 11 | 12 | void main() { 13 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 14 | } 15 | @end 16 | 17 | @fs fs_offscreen 18 | out vec4 FragColor; 19 | 20 | void main() { 21 | FragColor = vec4(0.0, 1.0, 0.0, 1.0); 22 | } 23 | @end 24 | 25 | 26 | @vs vs_display 27 | in vec2 a_pos; 28 | in vec2 a_tex_coords; 29 | out vec2 tex_coords; 30 | 31 | void main() { 32 | gl_Position = vec4(a_pos, 0.0, 1.0); 33 | tex_coords = a_tex_coords; 34 | } 35 | @end 36 | 37 | @fs fs_display 38 | in vec2 tex_coords; 39 | out vec4 frag_color; 40 | 41 | uniform sampler2D diffuse_texture; 42 | 43 | void main() { 44 | frag_color = texture(diffuse_texture, tex_coords); 45 | } 46 | @end 47 | 48 | @program offscreen vs_offscreen fs_offscreen 49 | @program display vs_display fs_display 50 | -------------------------------------------------------------------------------- /src/4-11-anti-aliasing/3-grayscale-msaa.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs_offscreen 4 | in vec3 a_pos; 5 | 6 | uniform vs_params { 7 | mat4 model; 8 | mat4 view; 9 | mat4 projection; 10 | }; 11 | 12 | void main() { 13 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 14 | } 15 | @end 16 | 17 | @fs fs_offscreen 18 | out vec4 FragColor; 19 | 20 | void main() { 21 | FragColor = vec4(0.0, 1.0, 0.0, 1.0); 22 | } 23 | @end 24 | 25 | 26 | @vs vs_display 27 | in vec2 a_pos; 28 | in vec2 a_tex_coords; 29 | out vec2 tex_coords; 30 | 31 | void main() { 32 | gl_Position = vec4(a_pos, 0.0, 1.0); 33 | tex_coords = a_tex_coords; 34 | } 35 | @end 36 | 37 | @fs fs_display 38 | in vec2 tex_coords; 39 | out vec4 frag_color; 40 | 41 | uniform sampler2D diffuse_texture; 42 | 43 | void main() { 44 | vec4 color = texture(diffuse_texture, tex_coords); 45 | float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; 46 | frag_color = vec4(average, average, average, 1.0); 47 | } 48 | @end 49 | 50 | @program offscreen vs_offscreen fs_offscreen 51 | @program display vs_display fs_display 52 | -------------------------------------------------------------------------------- /src/4-11-anti-aliasing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-11-1-msaa windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-msaa.c) 4 | sokol_shader(1-msaa.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(4-11-2-offscreen-msaa windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-offscreen-msaa.c) 11 | sokol_shader(2-offscreen-msaa.glsl ${slang}) 12 | fips_deps(sokol) 13 | fips_end_app() 14 | 15 | fips_begin_app(4-11-3-grayscale-msaa windowed) 16 | fips_vs_warning_level(3) 17 | fips_files(3-grayscale-msaa.c) 18 | sokol_shader(3-grayscale-msaa.glsl ${slang}) 19 | fips_deps(sokol) 20 | fips_end_app() 21 | -------------------------------------------------------------------------------- /src/4-2-stencil-testing/1-object-outlining.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @vs vs_outline 35 | in vec3 a_pos; 36 | 37 | uniform vs_params { 38 | mat4 model; 39 | mat4 view; 40 | mat4 projection; 41 | }; 42 | 43 | void main() { 44 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 45 | } 46 | @end 47 | 48 | @fs fs_outline 49 | out vec4 frag_color; 50 | 51 | void main() { 52 | frag_color = vec4(0.04, 0.28, 0.26, 1.0); 53 | } 54 | @end 55 | 56 | @program phong vs fs 57 | @program outline vs_outline fs_outline 58 | -------------------------------------------------------------------------------- /src/4-2-stencil-testing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-2-1-object-outlining windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-object-outlining.c) 4 | sokol_shader(1-object-outlining.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | -------------------------------------------------------------------------------- /src/4-2-stencil-testing/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - marble.jpg 7 | - metal.png 8 | -------------------------------------------------------------------------------- /src/4-3-blending/1-grass-opaque.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @program simple vs fs 35 | -------------------------------------------------------------------------------- /src/4-3-blending/2-grass-transparent.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @fs fs_grass 35 | in vec2 tex_coords; 36 | 37 | out vec4 frag_color; 38 | 39 | uniform sampler2D diffuse_texture; 40 | 41 | void main() { 42 | vec4 tex_color = texture(diffuse_texture, tex_coords); 43 | if (tex_color.a < 0.1) 44 | discard; 45 | frag_color = tex_color; 46 | } 47 | @end 48 | 49 | @program simple vs fs 50 | @program grass vs fs_grass 51 | -------------------------------------------------------------------------------- /src/4-3-blending/3-blending.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @program simple vs fs 35 | -------------------------------------------------------------------------------- /src/4-3-blending/4-blending-sorted.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @program simple vs fs 35 | -------------------------------------------------------------------------------- /src/4-3-blending/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-3-1-grass-opaque windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-grass-opaque.c) 4 | sokol_shader(1-grass-opaque.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(4-3-2-grass-transparent windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-grass-transparent.c) 12 | sokol_shader(2-grass-transparent.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(4-3-3-blending windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-blending.c) 20 | sokol_shader(3-blending.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | 25 | fips_begin_app(4-3-4-blending-sorted windowed) 26 | fips_vs_warning_level(3) 27 | fips_files(4-blending-sorted.c) 28 | sokol_shader(4-blending-sorted.glsl ${slang}) 29 | fipsutil_copy(textures-assets.yml) 30 | fips_deps(sokol) 31 | fips_end_app() 32 | -------------------------------------------------------------------------------- /src/4-3-blending/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - marble.jpg 7 | - metal.png 8 | - grass.png 9 | - transparent_window.png 10 | -------------------------------------------------------------------------------- /src/4-4-face-culling/1-cull-front.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @program simple vs fs 35 | -------------------------------------------------------------------------------- /src/4-4-face-culling/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-4-1-cull-front windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-cull-front.c) 4 | sokol_shader(1-cull-front.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | -------------------------------------------------------------------------------- /src/4-5-framebuffers/1-render-to-texture.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec2 hmm_vec2 2 | @ctype vec3 hmm_vec3 3 | @ctype mat4 hmm_mat4 4 | 5 | @vs vs_offscreen 6 | in vec3 a_pos; 7 | in vec2 a_tex_coords; 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @vs vs_display 23 | in vec2 a_pos; 24 | in vec2 a_tex_coords; 25 | out vec2 tex_coords; 26 | 27 | void main() { 28 | gl_Position = vec4(a_pos, 0.0, 1.0); 29 | tex_coords = a_tex_coords; 30 | } 31 | @end 32 | 33 | @fs fs 34 | in vec2 tex_coords; 35 | out vec4 frag_color; 36 | 37 | uniform sampler2D diffuse_texture; 38 | 39 | void main() { 40 | frag_color = texture(diffuse_texture, tex_coords); 41 | } 42 | @end 43 | 44 | @program offscreen vs_offscreen fs 45 | @program display vs_display fs 46 | -------------------------------------------------------------------------------- /src/4-5-framebuffers/2-inversion.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec2 hmm_vec2 2 | @ctype vec3 hmm_vec3 3 | @ctype mat4 hmm_mat4 4 | 5 | @vs vs_offscreen 6 | in vec3 a_pos; 7 | in vec2 a_tex_coords; 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @vs vs_display 23 | in vec2 a_pos; 24 | in vec2 a_tex_coords; 25 | out vec2 tex_coords; 26 | 27 | void main() { 28 | gl_Position = vec4(a_pos, 0.0, 1.0); 29 | tex_coords = a_tex_coords; 30 | } 31 | @end 32 | 33 | @fs fs_offscreen 34 | in vec2 tex_coords; 35 | out vec4 frag_color; 36 | 37 | uniform sampler2D diffuse_texture; 38 | 39 | void main() { 40 | frag_color = texture(diffuse_texture, tex_coords); 41 | } 42 | @end 43 | 44 | @fs fs_display 45 | in vec2 tex_coords; 46 | out vec4 frag_color; 47 | 48 | uniform sampler2D diffuse_texture; 49 | 50 | void main() { 51 | frag_color = vec4(vec3(1.0 - texture(diffuse_texture, tex_coords)), 1.0); 52 | } 53 | @end 54 | 55 | @program offscreen vs_offscreen fs_offscreen 56 | @program display vs_display fs_display 57 | -------------------------------------------------------------------------------- /src/4-5-framebuffers/3-grayscale.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec2 hmm_vec2 2 | @ctype vec3 hmm_vec3 3 | @ctype mat4 hmm_mat4 4 | 5 | @vs vs_offscreen 6 | in vec3 a_pos; 7 | in vec2 a_tex_coords; 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @vs vs_display 23 | in vec2 a_pos; 24 | in vec2 a_tex_coords; 25 | out vec2 tex_coords; 26 | 27 | void main() { 28 | gl_Position = vec4(a_pos, 0.0, 1.0); 29 | tex_coords = a_tex_coords; 30 | } 31 | @end 32 | 33 | @fs fs_offscreen 34 | in vec2 tex_coords; 35 | out vec4 frag_color; 36 | 37 | uniform sampler2D diffuse_texture; 38 | 39 | void main() { 40 | frag_color = texture(diffuse_texture, tex_coords); 41 | } 42 | @end 43 | 44 | @fs fs_display 45 | in vec2 tex_coords; 46 | out vec4 frag_color; 47 | 48 | uniform sampler2D diffuse_texture; 49 | 50 | void main() { 51 | vec4 color = texture(diffuse_texture, tex_coords); 52 | float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b; 53 | frag_color = vec4(average, average, average, 1.0); 54 | } 55 | @end 56 | 57 | @program offscreen vs_offscreen fs_offscreen 58 | @program display vs_display fs_display 59 | -------------------------------------------------------------------------------- /src/4-5-framebuffers/4-sharpen.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec2 hmm_vec2 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs_offscreen 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | out vec2 tex_coords; 8 | 9 | uniform vs_params { 10 | mat4 model; 11 | mat4 view; 12 | mat4 projection; 13 | }; 14 | 15 | void main() { 16 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 17 | tex_coords = a_tex_coords; 18 | } 19 | @end 20 | 21 | @vs vs_display 22 | in vec2 a_pos; 23 | in vec2 a_tex_coords; 24 | out vec2 tex_coords; 25 | 26 | void main() { 27 | gl_Position = vec4(a_pos, 0.0, 1.0); 28 | tex_coords = a_tex_coords; 29 | } 30 | @end 31 | 32 | @fs fs_offscreen 33 | in vec2 tex_coords; 34 | out vec4 frag_color; 35 | 36 | uniform sampler2D diffuse_texture; 37 | 38 | void main() { 39 | frag_color = texture(diffuse_texture, tex_coords); 40 | } 41 | @end 42 | 43 | @fs fs_display 44 | in vec2 tex_coords; 45 | out vec4 frag_color; 46 | 47 | uniform sampler2D diffuse_texture; 48 | 49 | uniform fs_params { 50 | vec2 offset; 51 | }; 52 | 53 | void main() { 54 | /* GLSL ES 1.0 (WebGL 1.0) does not support array constructor */ 55 | vec2 offsets[9]; 56 | offsets[0] = vec2(-offset.x, offset.y); // top-left 57 | offsets[1] = vec2( 0.0, offset.y); // top-center 58 | offsets[2] = vec2( offset.x, offset.y); // top-right 59 | offsets[3] = vec2(-offset.x, 0.0); // center-left 60 | offsets[4] = vec2( 0.0, 0.0); // center-center 61 | offsets[5] = vec2( offset.x, 0.0); // center-right 62 | offsets[6] = vec2(-offset.x, -offset.y); // bottom-left 63 | offsets[7] = vec2( 0.0, -offset.y); // bottom-center 64 | offsets[8] = vec2( offset.x, -offset.y); // bottom-right 65 | 66 | float kernel[9]; 67 | kernel[0] = kernel[1] = kernel[2] = kernel[3] = -1.; 68 | kernel[4] = 9.; 69 | kernel[5] = kernel[6] = kernel[7] = kernel[8] = -1.; 70 | 71 | vec3 sample_tex[9]; 72 | for(int i = 0; i < 9; i++) { 73 | sample_tex[i] = vec3(texture(diffuse_texture, tex_coords.st + offsets[i])); 74 | } 75 | 76 | vec3 color = vec3(0.0); 77 | for(int i = 0; i < 9; i++) 78 | color += sample_tex[i] * kernel[i]; 79 | 80 | frag_color = vec4(color, 1.0); 81 | } 82 | @end 83 | 84 | @program offscreen vs_offscreen fs_offscreen 85 | @program display vs_display fs_display 86 | -------------------------------------------------------------------------------- /src/4-5-framebuffers/5-blur.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec2 hmm_vec2 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs_offscreen 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | out vec2 tex_coords; 8 | 9 | uniform vs_params { 10 | mat4 model; 11 | mat4 view; 12 | mat4 projection; 13 | }; 14 | 15 | void main() { 16 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 17 | tex_coords = a_tex_coords; 18 | } 19 | @end 20 | 21 | @vs vs_display 22 | in vec2 a_pos; 23 | in vec2 a_tex_coords; 24 | out vec2 tex_coords; 25 | 26 | void main() { 27 | gl_Position = vec4(a_pos, 0.0, 1.0); 28 | tex_coords = a_tex_coords; 29 | } 30 | @end 31 | 32 | @fs fs_offscreen 33 | in vec2 tex_coords; 34 | out vec4 frag_color; 35 | 36 | uniform sampler2D diffuse_texture; 37 | 38 | void main() { 39 | frag_color = texture(diffuse_texture, tex_coords); 40 | } 41 | @end 42 | 43 | @fs fs_display 44 | in vec2 tex_coords; 45 | out vec4 frag_color; 46 | 47 | uniform sampler2D diffuse_texture; 48 | 49 | uniform fs_params { 50 | vec2 offset; 51 | }; 52 | 53 | void main() { 54 | /* GLSL ES 1.0 (WebGL 1.0) does not support array constructor */ 55 | vec2 offsets[9]; 56 | offsets[0] = vec2(-offset.x, offset.y); // top-left 57 | offsets[1] = vec2( 0.0, offset.y); // top-center 58 | offsets[2] = vec2( offset.x, offset.y); // top-right 59 | offsets[3] = vec2(-offset.x, 0.0); // center-left 60 | offsets[4] = vec2( 0.0, 0.0); // center-center 61 | offsets[5] = vec2( offset.x, 0.0); // center-right 62 | offsets[6] = vec2(-offset.x, -offset.y); // bottom-left 63 | offsets[7] = vec2( 0.0, -offset.y); // bottom-center 64 | offsets[8] = vec2( offset.x, -offset.y); // bottom-right 65 | 66 | float kernel[9]; 67 | kernel[0] = kernel[2] = kernel[6] = kernel[8] = 1. / 16.; 68 | kernel[4] = 4. / 16.; 69 | kernel[1] = kernel[3] = kernel[5] = kernel[7] = 2. / 16.; 70 | 71 | vec3 sample_tex[9]; 72 | for(int i = 0; i < 9; i++) { 73 | sample_tex[i] = vec3(texture(diffuse_texture, tex_coords.st + offsets[i])); 74 | } 75 | 76 | vec3 color = vec3(0.0); 77 | for(int i = 0; i < 9; i++) 78 | color += sample_tex[i] * kernel[i]; 79 | 80 | frag_color = vec4(color, 1.0); 81 | } 82 | @end 83 | 84 | @program offscreen vs_offscreen fs_offscreen 85 | @program display vs_display fs_display 86 | -------------------------------------------------------------------------------- /src/4-5-framebuffers/6-edge-detection.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec2 hmm_vec2 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs_offscreen 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | out vec2 tex_coords; 8 | 9 | uniform vs_params { 10 | mat4 model; 11 | mat4 view; 12 | mat4 projection; 13 | }; 14 | 15 | void main() { 16 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 17 | tex_coords = a_tex_coords; 18 | } 19 | @end 20 | 21 | @vs vs_display 22 | in vec2 a_pos; 23 | in vec2 a_tex_coords; 24 | out vec2 tex_coords; 25 | 26 | void main() { 27 | gl_Position = vec4(a_pos, 0.0, 1.0); 28 | tex_coords = a_tex_coords; 29 | } 30 | @end 31 | 32 | @fs fs_offscreen 33 | in vec2 tex_coords; 34 | out vec4 frag_color; 35 | 36 | uniform sampler2D diffuse_texture; 37 | 38 | void main() { 39 | frag_color = texture(diffuse_texture, tex_coords); 40 | } 41 | @end 42 | 43 | @fs fs_display 44 | in vec2 tex_coords; 45 | out vec4 frag_color; 46 | 47 | uniform sampler2D diffuse_texture; 48 | 49 | uniform fs_params { 50 | vec2 offset; 51 | }; 52 | 53 | void main() { 54 | /* GLSL ES 1.0 (WebGL 1.0) does not support array constructor */ 55 | vec2 offsets[9]; 56 | offsets[0] = vec2(-offset.x, offset.y); // top-left 57 | offsets[1] = vec2( 0.0, offset.y); // top-center 58 | offsets[2] = vec2( offset.x, offset.y); // top-right 59 | offsets[3] = vec2(-offset.x, 0.0); // center-left 60 | offsets[4] = vec2( 0.0, 0.0); // center-center 61 | offsets[5] = vec2( offset.x, 0.0); // center-right 62 | offsets[6] = vec2(-offset.x, -offset.y); // bottom-left 63 | offsets[7] = vec2( 0.0, -offset.y); // bottom-center 64 | offsets[8] = vec2( offset.x, -offset.y); // bottom-right 65 | 66 | float kernel[9]; 67 | kernel[0] = kernel[1] = kernel[2] = kernel[3] = 1.; 68 | kernel[4] = -8.; 69 | kernel[5] = kernel[6] = kernel[7] = kernel[8] = 1.; 70 | 71 | vec3 sample_tex[9]; 72 | for(int i = 0; i < 9; i++) { 73 | sample_tex[i] = vec3(texture(diffuse_texture, tex_coords.st + offsets[i])); 74 | } 75 | 76 | vec3 color = vec3(0.0); 77 | for(int i = 0; i < 9; i++) 78 | color += sample_tex[i] * kernel[i]; 79 | 80 | frag_color = vec4(color, 1.0); 81 | } 82 | @end 83 | 84 | @program offscreen vs_offscreen fs_offscreen 85 | @program display vs_display fs_display 86 | -------------------------------------------------------------------------------- /src/4-5-framebuffers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-5-1-render-to-texture windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-render-to-texture.c) 4 | sokol_shader(1-render-to-texture.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(4-5-2-inversion windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-inversion.c) 12 | sokol_shader(2-inversion.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(4-5-3-grayscale windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-grayscale.c) 20 | sokol_shader(3-grayscale.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | 25 | fips_begin_app(4-5-4-sharpen windowed) 26 | fips_vs_warning_level(3) 27 | fips_files(4-sharpen.c) 28 | sokol_shader(4-sharpen.glsl ${slang}) 29 | fipsutil_copy(textures-assets.yml) 30 | fips_deps(sokol) 31 | fips_end_app() 32 | 33 | fips_begin_app(4-5-5-blur windowed) 34 | fips_vs_warning_level(3) 35 | fips_files(5-blur.c) 36 | sokol_shader(5-blur.glsl ${slang}) 37 | fipsutil_copy(textures-assets.yml) 38 | fips_deps(sokol) 39 | fips_end_app() 40 | 41 | fips_begin_app(4-5-6-edge-detection windowed) 42 | fips_vs_warning_level(3) 43 | fips_files(6-edge-detection.c) 44 | sokol_shader(6-edge-detection.glsl ${slang}) 45 | fipsutil_copy(textures-assets.yml) 46 | fips_deps(sokol) 47 | fips_end_app() 48 | -------------------------------------------------------------------------------- /src/4-5-framebuffers/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container.jpg 7 | - metal.png 8 | -------------------------------------------------------------------------------- /src/4-6-cubemaps/1-skybox.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec2 a_tex_coords; 7 | 8 | out vec2 tex_coords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 18 | tex_coords = a_tex_coords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 tex_coords; 24 | 25 | out vec4 frag_color; 26 | 27 | uniform sampler2D diffuse_texture; 28 | 29 | void main() { 30 | frag_color = texture(diffuse_texture, tex_coords); 31 | } 32 | @end 33 | 34 | @vs vs_skybox 35 | in vec3 a_pos; 36 | 37 | out vec3 tex_coords; 38 | 39 | uniform vs_params { 40 | mat4 model; 41 | mat4 view; 42 | mat4 projection; 43 | }; 44 | 45 | void main() { 46 | tex_coords = a_pos; 47 | vec4 pos = projection * view * vec4(a_pos, 1.0); 48 | gl_Position = pos.xyww; 49 | } 50 | @end 51 | 52 | @fs fs_skybox 53 | in vec3 tex_coords; 54 | 55 | out vec4 frag_color; 56 | 57 | uniform samplerCube skybox_texture; 58 | 59 | void main() { 60 | frag_color = texture(skybox_texture, tex_coords); 61 | } 62 | @end 63 | 64 | @program simple vs fs 65 | @program skybox vs_skybox fs_skybox 66 | -------------------------------------------------------------------------------- /src/4-6-cubemaps/2-reflection-cube.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec3 a_normal; 7 | 8 | out vec3 normal; 9 | out vec3 position; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | // inverse tranpose is left out because: 19 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 20 | // (b) we're not performing non-uniform scale 21 | normal = mat3(model) * a_normal; 22 | position = vec3(model * vec4(a_pos, 1.0)); 23 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 normal; 29 | in vec3 position; 30 | 31 | out vec4 frag_color; 32 | 33 | uniform fs_params { 34 | vec3 camera_pos; 35 | }; 36 | 37 | uniform samplerCube skybox_texture; 38 | 39 | void main() { 40 | vec3 I = normalize(position - camera_pos); 41 | vec3 R = reflect(I, normalize(normal)); 42 | frag_color = vec4(texture(skybox_texture, R).rgb, 1.0); 43 | } 44 | @end 45 | 46 | @vs vs_skybox 47 | in vec3 a_pos; 48 | 49 | out vec3 tex_coords; 50 | 51 | uniform vs_params { 52 | mat4 model; 53 | mat4 view; 54 | mat4 projection; 55 | }; 56 | 57 | void main() { 58 | tex_coords = a_pos; 59 | vec4 pos = projection * view * vec4(a_pos, 1.0); 60 | gl_Position = pos.xyww; 61 | } 62 | @end 63 | 64 | @fs fs_skybox 65 | in vec3 tex_coords; 66 | 67 | out vec4 frag_color; 68 | 69 | uniform samplerCube skybox_texture; 70 | 71 | void main() { 72 | frag_color = texture(skybox_texture, tex_coords); 73 | } 74 | @end 75 | 76 | @program simple vs fs 77 | @program skybox vs_skybox fs_skybox 78 | -------------------------------------------------------------------------------- /src/4-6-cubemaps/3-reflection-backpack.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec3 a_normal; 7 | 8 | out vec3 normal; 9 | out vec3 position; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | // inverse tranpose is left out because: 19 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 20 | // (b) we're not performing non-uniform scale 21 | normal = mat3(model) * a_normal; 22 | position = vec3(model * vec4(a_pos, 1.0)); 23 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 normal; 29 | in vec3 position; 30 | 31 | out vec4 frag_color; 32 | 33 | uniform fs_params { 34 | vec3 camera_pos; 35 | }; 36 | 37 | uniform samplerCube skybox_texture; 38 | 39 | void main() { 40 | vec3 I = normalize(position - camera_pos); 41 | vec3 R = reflect(I, normalize(normal)); 42 | frag_color = vec4(texture(skybox_texture, R).rgb, 1.0); 43 | } 44 | @end 45 | 46 | @vs vs_skybox 47 | in vec3 a_pos; 48 | 49 | out vec3 tex_coords; 50 | 51 | uniform vs_params { 52 | mat4 model; 53 | mat4 view; 54 | mat4 projection; 55 | }; 56 | 57 | void main() { 58 | tex_coords = a_pos; 59 | vec4 pos = projection * view * vec4(a_pos, 1.0); 60 | gl_Position = pos.xyww; 61 | } 62 | @end 63 | 64 | @fs fs_skybox 65 | in vec3 tex_coords; 66 | 67 | out vec4 frag_color; 68 | 69 | uniform samplerCube skybox_texture; 70 | 71 | void main() { 72 | frag_color = texture(skybox_texture, tex_coords); 73 | } 74 | @end 75 | 76 | @program simple vs fs 77 | @program skybox vs_skybox fs_skybox 78 | -------------------------------------------------------------------------------- /src/4-6-cubemaps/4-refraction-cube.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec3 a_normal; 7 | 8 | out vec3 normal; 9 | out vec3 position; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | // inverse tranpose is left out because: 19 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 20 | // (b) we're not performing non-uniform scale 21 | normal = mat3(model) * a_normal; 22 | position = vec3(model * vec4(a_pos, 1.0)); 23 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 normal; 29 | in vec3 position; 30 | 31 | out vec4 frag_color; 32 | 33 | uniform fs_params { 34 | vec3 camera_pos; 35 | }; 36 | 37 | uniform samplerCube skybox_texture; 38 | 39 | void main() { 40 | float ratio = 1.00 / 1.52; 41 | vec3 I = normalize(position - camera_pos); 42 | vec3 R = refract(I, normalize(normal), ratio); 43 | frag_color = vec4(texture(skybox_texture, R).rgb, 1.0); 44 | } 45 | @end 46 | 47 | @vs vs_skybox 48 | in vec3 a_pos; 49 | 50 | out vec3 tex_coords; 51 | 52 | uniform vs_params { 53 | mat4 model; 54 | mat4 view; 55 | mat4 projection; 56 | }; 57 | 58 | void main() { 59 | tex_coords = a_pos; 60 | vec4 pos = projection * view * vec4(a_pos, 1.0); 61 | gl_Position = pos.xyww; 62 | } 63 | @end 64 | 65 | @fs fs_skybox 66 | in vec3 tex_coords; 67 | 68 | out vec4 frag_color; 69 | 70 | uniform samplerCube skybox_texture; 71 | 72 | void main() { 73 | frag_color = texture(skybox_texture, tex_coords); 74 | } 75 | @end 76 | 77 | @program simple vs fs 78 | @program skybox vs_skybox fs_skybox 79 | -------------------------------------------------------------------------------- /src/4-6-cubemaps/5-refraction-backpack.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec3 a_normal; 7 | 8 | out vec3 normal; 9 | out vec3 position; 10 | 11 | uniform vs_params { 12 | mat4 model; 13 | mat4 view; 14 | mat4 projection; 15 | }; 16 | 17 | void main() { 18 | // inverse tranpose is left out because: 19 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 20 | // (b) we're not performing non-uniform scale 21 | normal = mat3(model) * a_normal; 22 | position = vec3(model * vec4(a_pos, 1.0)); 23 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 24 | } 25 | @end 26 | 27 | @fs fs 28 | in vec3 normal; 29 | in vec3 position; 30 | 31 | out vec4 frag_color; 32 | 33 | uniform fs_params { 34 | vec3 camera_pos; 35 | }; 36 | 37 | uniform samplerCube skybox_texture; 38 | 39 | void main() { 40 | float ratio = 1.00 / 1.52; 41 | vec3 I = normalize(position - camera_pos); 42 | vec3 R = refract(I, normalize(normal), ratio); 43 | frag_color = vec4(texture(skybox_texture, R).rgb, 1.0); 44 | } 45 | @end 46 | 47 | @vs vs_skybox 48 | in vec3 a_pos; 49 | 50 | out vec3 tex_coords; 51 | 52 | uniform vs_params { 53 | mat4 model; 54 | mat4 view; 55 | mat4 projection; 56 | }; 57 | 58 | void main() { 59 | tex_coords = a_pos; 60 | vec4 pos = projection * view * vec4(a_pos, 1.0); 61 | gl_Position = pos.xyww; 62 | } 63 | @end 64 | 65 | @fs fs_skybox 66 | in vec3 tex_coords; 67 | 68 | out vec4 frag_color; 69 | 70 | uniform samplerCube skybox_texture; 71 | 72 | void main() { 73 | frag_color = texture(skybox_texture, tex_coords); 74 | } 75 | @end 76 | 77 | @program simple vs fs 78 | @program skybox vs_skybox fs_skybox 79 | -------------------------------------------------------------------------------- /src/4-6-cubemaps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-6-1-skybox windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-skybox.c) 4 | sokol_shader(1-skybox.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(4-6-2-reflection-cube windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-reflection-cube.c) 12 | sokol_shader(2-reflection-cube.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(4-6-3-reflection-backpack windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-reflection-backpack.c) 20 | sokol_shader(3-reflection-backpack.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | 25 | fips_begin_app(4-6-4-refraction-cube windowed) 26 | fips_vs_warning_level(3) 27 | fips_files(4-refraction-cube.c) 28 | sokol_shader(4-refraction-cube.glsl ${slang}) 29 | fipsutil_copy(textures-assets.yml) 30 | fips_deps(sokol) 31 | fips_end_app() 32 | 33 | fips_begin_app(4-6-5-refraction-backpack windowed) 34 | fips_vs_warning_level(3) 35 | fips_files(5-refraction-backpack.c) 36 | sokol_shader(5-refraction-backpack.glsl ${slang}) 37 | fipsutil_copy(textures-assets.yml) 38 | fips_deps(sokol) 39 | fips_end_app() 40 | -------------------------------------------------------------------------------- /src/4-6-cubemaps/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - container.jpg 7 | - skybox_right.jpg 8 | - skybox_left.jpg 9 | - skybox_top.jpg 10 | - skybox_bottom.jpg 11 | - skybox_front.jpg 12 | - skybox_back.jpg 13 | - backpack.mtl 14 | - backpack.obj 15 | -------------------------------------------------------------------------------- /src/4-8-advanced-glsl/1-point-size.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Advanced GLSL (1) 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "hmm/HandmadeMath.h" 7 | #include "1-point-size.glsl.h" 8 | #define LOPGL_APP_IMPL 9 | #include "../lopgl_app.h" 10 | 11 | /* application state */ 12 | static struct { 13 | sg_pipeline pip; 14 | sg_bindings bind; 15 | sg_pass_action pass_action; 16 | } state; 17 | 18 | static void init(void) { 19 | lopgl_setup(); 20 | 21 | float vertices[] = { 22 | 0.0f, 0.0f, 0.0f, 23 | -0.5f, -0.5f, -0.5f, 24 | 0.5f, -0.5f, -0.5f, 25 | -0.5f, 0.5f, -0.5f, 26 | 0.5f, 0.5f, -0.5f, 27 | -0.5f, 0.5f, 0.5f, 28 | -0.5f, -0.5f, 0.5f, 29 | }; 30 | 31 | state.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ 32 | .size = sizeof(vertices), 33 | .content = vertices, 34 | .label = "vertices" 35 | }); 36 | 37 | /* create shader from code-generated sg_shader_desc */ 38 | sg_shader shd = sg_make_shader(simple_shader_desc()); 39 | 40 | /* create a pipeline object */ 41 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 42 | .shader = shd, 43 | /* if the vertex layout doesn't have gaps, don't need to provide strides and offsets */ 44 | .layout = { 45 | .attrs = { 46 | [ATTR_vs_aPos].format = SG_VERTEXFORMAT_FLOAT3 47 | } 48 | }, 49 | .primitive_type = SG_PRIMITIVETYPE_POINTS, 50 | .label = "points-pipeline" 51 | }); 52 | 53 | /* a pass action to clear framebuffer */ 54 | state.pass_action = (sg_pass_action) { 55 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.1f, 0.1f, 0.1f, 1.0f} } 56 | }; 57 | } 58 | 59 | void frame(void) { 60 | lopgl_update(); 61 | 62 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 63 | 64 | hmm_mat4 view = lopgl_view_matrix(); 65 | hmm_mat4 projection = HMM_Perspective(lopgl_fov(), (float)sapp_width() / (float)sapp_height(), 0.1f, 100.0f); 66 | 67 | vs_params_t vs_params = { 68 | .view = view, 69 | .projection = projection 70 | }; 71 | 72 | sg_apply_pipeline(state.pip); 73 | sg_apply_bindings(&state.bind); 74 | 75 | vs_params.model = HMM_Mat4d(1.f);; 76 | sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_params, &vs_params, sizeof(vs_params)); 77 | 78 | sg_draw(0, 7, 1); 79 | 80 | lopgl_render_help(); 81 | 82 | sg_end_pass(); 83 | sg_commit(); 84 | } 85 | 86 | void event(const sapp_event* e) { 87 | lopgl_handle_input(e); 88 | } 89 | 90 | 91 | void cleanup(void) { 92 | lopgl_shutdown(); 93 | } 94 | 95 | sapp_desc sokol_main(int argc, char* argv[]) { 96 | return (sapp_desc){ 97 | .init_cb = init, 98 | .frame_cb = frame, 99 | .cleanup_cb = cleanup, 100 | .event_cb = event, 101 | .width = 800, 102 | .height = 600, 103 | .gl_force_gles2 = true, 104 | .window_title = "Point Size (LearnOpenGL)", 105 | }; 106 | } 107 | -------------------------------------------------------------------------------- /src/4-8-advanced-glsl/1-point-size.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | 7 | uniform vs_params { 8 | mat4 model; 9 | mat4 view; 10 | mat4 projection; 11 | }; 12 | 13 | void main() { 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | gl_PointSize = gl_Position.z; 16 | } 17 | @end 18 | 19 | @fs fs 20 | out vec4 FragColor; 21 | 22 | void main() { 23 | FragColor = vec4(1.0, 0.3, 0.6, 1.0); 24 | } 25 | @end 26 | 27 | @program simple vs fs 28 | -------------------------------------------------------------------------------- /src/4-8-advanced-glsl/2-frag-coord.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | 7 | uniform vs_params { 8 | mat4 model; 9 | mat4 view; 10 | mat4 projection; 11 | }; 12 | 13 | void main() { 14 | gl_Position = projection * view * model * vec4(aPos, 1.0); 15 | } 16 | @end 17 | 18 | @fs fs 19 | uniform fs_params { 20 | float center_x; 21 | }; 22 | 23 | out vec4 FragColor; 24 | 25 | void main() { 26 | if(gl_FragCoord.x < center_x) 27 | FragColor = vec4(1.0, 0.0, 0.0, 1.0); 28 | else 29 | FragColor = vec4(0.0, 1.0, 0.0, 1.0); 30 | } 31 | @end 32 | 33 | @program simple vs fs 34 | -------------------------------------------------------------------------------- /src/4-8-advanced-glsl/3-front-facing.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 aPos; 6 | in vec2 aTexCoords; 7 | 8 | out vec2 TexCoords; 9 | 10 | uniform vs_params { 11 | mat4 model; 12 | mat4 view; 13 | mat4 projection; 14 | }; 15 | 16 | void main() { 17 | gl_Position = projection * view * model * vec4(aPos, 1.0); 18 | TexCoords = aTexCoords; 19 | } 20 | @end 21 | 22 | @fs fs 23 | in vec2 TexCoords; 24 | 25 | out vec4 FragColor; 26 | 27 | uniform sampler2D front_texture; 28 | uniform sampler2D back_texture; 29 | 30 | void main() { 31 | if(gl_FrontFacing) 32 | FragColor = texture(front_texture, TexCoords); 33 | else 34 | FragColor = texture(back_texture, TexCoords); 35 | } 36 | @end 37 | 38 | @program simple vs fs 39 | -------------------------------------------------------------------------------- /src/4-8-advanced-glsl/4-uniform-buffers.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs 4 | in vec3 aPos; 5 | 6 | layout(binding=0) uniform vs_view_projection { 7 | mat4 view; 8 | mat4 projection; 9 | }; 10 | 11 | layout(binding=1) uniform vs_model { 12 | mat4 model; 13 | }; 14 | 15 | void main() { 16 | gl_Position = projection * view * model * vec4(aPos, 1.0); 17 | } 18 | @end 19 | 20 | @fs fs_red 21 | out vec4 FragColor; 22 | 23 | void main() { 24 | FragColor = vec4(1.0, 0.0, 0.0, 1.0); 25 | } 26 | @end 27 | 28 | @fs fs_green 29 | out vec4 FragColor; 30 | 31 | void main() { 32 | FragColor = vec4(0.0, 1.0, 0.0, 1.0); 33 | } 34 | @end 35 | 36 | @fs fs_blue 37 | out vec4 FragColor; 38 | 39 | void main() { 40 | FragColor = vec4(0.0, 0.0, 1.0, 1.0); 41 | } 42 | @end 43 | 44 | @fs fs_yellow 45 | out vec4 FragColor; 46 | 47 | void main() { 48 | FragColor = vec4(1.0, 1.0, 0.0, 1.0); 49 | } 50 | @end 51 | 52 | 53 | @program red vs fs_red 54 | @program green vs fs_green 55 | @program blue vs fs_blue 56 | @program yellow vs fs_yellow 57 | -------------------------------------------------------------------------------- /src/4-8-advanced-glsl/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(4-8-1-point-size windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-point-size.c) 4 | sokol_shader(1-point-size.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(4-8-2-frag-coord windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-frag-coord.c) 11 | sokol_shader(2-frag-coord.glsl ${slang}) 12 | fips_deps(sokol) 13 | fips_end_app() 14 | 15 | fips_begin_app(4-8-3-front-facing windowed) 16 | fips_vs_warning_level(3) 17 | fips_files(3-front-facing.c) 18 | sokol_shader(3-front-facing.glsl ${slang}) 19 | fipsutil_copy(textures-assets.yml) 20 | fips_deps(sokol) 21 | fips_end_app() 22 | 23 | fips_begin_app(4-8-4-uniform-buffers windowed) 24 | fips_vs_warning_level(3) 25 | fips_files(4-uniform-buffers.c) 26 | sokol_shader(4-uniform-buffers.glsl ${slang}) 27 | fips_deps(sokol) 28 | fips_end_app() -------------------------------------------------------------------------------- /src/4-8-advanced-glsl/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - uv_grid.png 7 | -------------------------------------------------------------------------------- /src/4-9-geometry-shader/1-lines.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Geometry Shader (1) 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #define LOPGL_APP_IMPL 8 | #include "../lopgl_app.h" 9 | #include "1-lines.glsl.h" 10 | #include "string.h" 11 | 12 | /* application state */ 13 | static struct { 14 | sg_pipeline pip; 15 | sg_bindings bind; 16 | sg_pass_action pass_action; 17 | } state; 18 | 19 | static void init(void) { 20 | lopgl_setup(); 21 | 22 | if (sapp_gles2()) { 23 | /* this demo needs GLES3/WebGL because we are using texelFetch in the shader */ 24 | return; 25 | } 26 | 27 | /* create shader from code-generated sg_shader_desc */ 28 | sg_shader shd = sg_make_shader(simple_shader_desc()); 29 | 30 | /* a pipeline state object */ 31 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 32 | .shader = shd, 33 | .layout = { 34 | .attrs = { 35 | /* dummy vertex attribute, otherwise sokol complains */ 36 | [ATTR_vs_a_dummy].format = SG_VERTEXFORMAT_FLOAT, 37 | } 38 | }, 39 | .primitive_type = SG_PRIMITIVETYPE_LINES, 40 | .label = "vertices-pipeline" 41 | }); 42 | 43 | /* a pass action to clear framebuffer */ 44 | state.pass_action = (sg_pass_action) { 45 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.1f, 0.1f, 0.1f, 1.0f} } 46 | }; 47 | 48 | float positions[] = { 49 | -0.5f, 0.5f, // top-left 50 | 0.5f, 0.5f, // top-right 51 | 0.5f, -0.5f, // bottom-right 52 | -0.5f, -0.5f // bottom-left 53 | }; 54 | 55 | state.bind.vs_images[SLOT_positions_texture] = sg_make_image(&(sg_image_desc){ 56 | .width = 16, 57 | .height = 1, 58 | .pixel_format = SG_PIXELFORMAT_RG32F, 59 | /* set filter to nearest, webgl2 does not support filtering for float textures */ 60 | .mag_filter = SG_FILTER_NEAREST, 61 | .min_filter = SG_FILTER_NEAREST, 62 | .content.subimage[0][0] = { 63 | .ptr = positions, 64 | .size = sizeof(positions) 65 | }, 66 | .label = "positions-texture" 67 | }); 68 | } 69 | 70 | void frame(void) { 71 | /* can't do anything useful on GLES2/WebGL */ 72 | if (sapp_gles2()) { 73 | lopgl_render_gles2_fallback(); 74 | return; 75 | } 76 | 77 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 78 | sg_apply_pipeline(state.pip); 79 | sg_apply_bindings(&state.bind); 80 | sg_draw(0, 4*2, 1); 81 | sg_end_pass(); 82 | sg_commit(); 83 | } 84 | 85 | void cleanup(void) { 86 | sg_shutdown(); 87 | } 88 | 89 | void event(const sapp_event* e) { 90 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 91 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 92 | sapp_request_quit(); 93 | } 94 | } 95 | } 96 | 97 | sapp_desc sokol_main(int argc, char* argv[]) { 98 | return (sapp_desc){ 99 | .init_cb = init, 100 | .frame_cb = frame, 101 | .cleanup_cb = cleanup, 102 | .event_cb = event, 103 | .width = 800, 104 | .height = 600, 105 | .window_title = "Lines (LearnOpenGL)", 106 | }; 107 | } 108 | -------------------------------------------------------------------------------- /src/4-9-geometry-shader/1-lines.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec4 hmm_vec4 2 | 3 | @vs vs 4 | in float a_dummy; // add a dummy vertex attribute otherwise sokol complains 5 | 6 | uniform sampler2D positions_texture; 7 | 8 | void main() { 9 | uint index = gl_VertexID >> 1; // divide by 2 10 | vec4 pos = texelFetch(positions_texture, ivec2(index, 0), 0); 11 | 12 | pos.x = gl_VertexID % 2 == 0 ? pos.x - 0.1 : pos.x + 0.1; 13 | gl_Position = vec4(pos.x, pos.y, 0.0, 1.0); 14 | } 15 | @end 16 | 17 | @fs fs 18 | out vec4 frag_color; 19 | 20 | void main() { 21 | frag_color = vec4(0.0, 1.0, 0.0, 1.0); 22 | } 23 | @end 24 | 25 | @program simple vs fs 26 | -------------------------------------------------------------------------------- /src/4-9-geometry-shader/2-houses.c: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // Geometry Shader (2) 3 | //------------------------------------------------------------------------------ 4 | #include "sokol_app.h" 5 | #include "sokol_gfx.h" 6 | #include "sokol_glue.h" 7 | #define LOPGL_APP_IMPL 8 | #include "../lopgl_app.h" 9 | #include "2-houses.glsl.h" 10 | #include "string.h" 11 | 12 | /* application state */ 13 | static struct { 14 | sg_pipeline pip; 15 | sg_bindings bind; 16 | sg_pass_action pass_action; 17 | } state; 18 | 19 | static void init(void) { 20 | lopgl_setup(); 21 | 22 | if (sapp_gles2()) { 23 | /* this demo needs GLES3/WebGL because we are using texelFetch in the shader */ 24 | return; 25 | } 26 | 27 | /* create shader from code-generated sg_shader_desc */ 28 | sg_shader shd = sg_make_shader(simple_shader_desc()); 29 | 30 | /* a pipeline state object */ 31 | state.pip = sg_make_pipeline(&(sg_pipeline_desc){ 32 | .shader = shd, 33 | .layout = { 34 | .attrs = { 35 | /* dummy vertex attribute, otherwise sokol complains */ 36 | [ATTR_vs_a_dummy].format = SG_VERTEXFORMAT_FLOAT, 37 | } 38 | }, 39 | .primitive_type = SG_PRIMITIVETYPE_TRIANGLES, 40 | .label = "vertices-pipeline" 41 | }); 42 | 43 | /* a pass action to clear framebuffer */ 44 | state.pass_action = (sg_pass_action) { 45 | .colors[0] = { .action=SG_ACTION_CLEAR, .val={0.1f, 0.1f, 0.1f, 1.0f} } 46 | }; 47 | 48 | float positions[] = { 49 | -0.5f, 0.5f, // top-left 50 | 0.5f, 0.5f, // top-right 51 | 0.5f, -0.5f, // bottom-right 52 | -0.5f, -0.5f // bottom-left 53 | }; 54 | 55 | state.bind.vs_images[SLOT_position_texture] = sg_make_image(&(sg_image_desc){ 56 | .width = 4, 57 | .height = 1, 58 | .pixel_format = SG_PIXELFORMAT_RG32F, 59 | /* set filter to nearest, webgl2 does not support filtering for float textures */ 60 | .mag_filter = SG_FILTER_NEAREST, 61 | .min_filter = SG_FILTER_NEAREST, 62 | .content.subimage[0][0] = { 63 | .ptr = positions, 64 | .size = sizeof(positions) 65 | }, 66 | .label = "positions-texture" 67 | }); 68 | 69 | float colors[] = { 70 | 1.0f, 0.0f, 0.0f, 1.0, // top-left 71 | 0.0f, 1.0f, 0.0f, 1.0, // top-right 72 | 0.0f, 0.0f, 1.0f, 1.0, // bottom-right 73 | 1.0f, 1.0f, 0.0f, 1.0 // bottom-left 74 | }; 75 | 76 | state.bind.vs_images[SLOT_color_texture] = sg_make_image(&(sg_image_desc){ 77 | .width = 4, 78 | .height = 1, 79 | .pixel_format = SG_PIXELFORMAT_RGBA32F, 80 | /* set filter to nearest, webgl2 does not support filtering for float textures */ 81 | .mag_filter = SG_FILTER_NEAREST, 82 | .min_filter = SG_FILTER_NEAREST, 83 | .content.subimage[0][0] = { 84 | .ptr = colors, 85 | .size = sizeof(colors) 86 | }, 87 | .label = "color-texture" 88 | }); 89 | } 90 | 91 | void frame(void) { 92 | /* can't do anything useful on GLES2/WebGL */ 93 | if (sapp_gles2()) { 94 | lopgl_render_gles2_fallback(); 95 | return; 96 | } 97 | 98 | sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height()); 99 | sg_apply_pipeline(state.pip); 100 | sg_apply_bindings(&state.bind); 101 | sg_draw(0, 4*9, 1); 102 | sg_end_pass(); 103 | sg_commit(); 104 | } 105 | 106 | void cleanup(void) { 107 | sg_shutdown(); 108 | } 109 | 110 | void event(const sapp_event* e) { 111 | if (e->type == SAPP_EVENTTYPE_KEY_DOWN) { 112 | if (e->key_code == SAPP_KEYCODE_ESCAPE) { 113 | sapp_request_quit(); 114 | } 115 | } 116 | } 117 | 118 | sapp_desc sokol_main(int argc, char* argv[]) { 119 | return (sapp_desc){ 120 | .init_cb = init, 121 | .frame_cb = frame, 122 | .cleanup_cb = cleanup, 123 | .event_cb = event, 124 | .width = 800, 125 | .height = 600, 126 | .window_title = "Houses (LearnOpenGL)", 127 | }; 128 | } 129 | -------------------------------------------------------------------------------- /src/4-9-geometry-shader/2-houses.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec4 hmm_vec4 2 | 3 | @vs vs 4 | in float a_dummy; // add a dummy vertex attribute otherwise sokol complains 5 | out vec4 color; 6 | 7 | uniform sampler2D position_texture; 8 | uniform sampler2D color_texture; 9 | 10 | void main() { 11 | uint pos_index = gl_VertexID / 9; 12 | vec4 pos = texelFetch(position_texture, ivec2(pos_index, 0), 0); 13 | 14 | uint index = gl_VertexID % 9; 15 | vec2 offset = index == 0 ? vec2(-0.2, 0.2) : vec2(0.0, 0.0); 16 | offset = index == 1 ? vec2(0.2, -0.2) : offset; 17 | offset = index == 2 ? vec2(-0.2, -0.2) : offset; 18 | offset = index == 3 ? vec2(-0.2, 0.2) : offset; 19 | offset = index == 4 ? vec2(0.2, 0.2) : offset; 20 | offset = index == 5 ? vec2(0.2, -0.2) : offset; 21 | offset = index == 6 ? vec2(-0.2, 0.2) : offset; 22 | offset = index == 7 ? vec2(0.0, 0.4) : offset; 23 | offset = index == 8 ? vec2(0.2, 0.2) : offset; 24 | gl_Position = vec4(pos.x + offset.x, pos.y + offset.y, 0.0, 1.0); 25 | 26 | color = texelFetch(color_texture, ivec2(pos_index, 0), 0); 27 | color = index == 7 ? vec4(1.0, 1.0, 1.0, 1.0) : color; 28 | } 29 | @end 30 | 31 | @fs fs 32 | in vec4 color; 33 | out vec4 frag_color; 34 | 35 | void main() { 36 | frag_color = color; 37 | } 38 | @end 39 | 40 | @program simple vs fs 41 | -------------------------------------------------------------------------------- /src/4-9-geometry-shader/3-exploding-object.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @vs vs 4 | in float a_dummy; // add a dummy vertex attribute otherwise sokol complains 5 | out vec2 tex_coords; 6 | 7 | uniform vs_params { 8 | mat4 model; 9 | mat4 view; 10 | mat4 projection; 11 | float time; 12 | }; 13 | 14 | uniform sampler2D vertex_texture; 15 | 16 | float getVal(uint index) { 17 | float x = index % 1024; 18 | float y = index / 1024; 19 | return texelFetch(vertex_texture, ivec2(x, y), 0).r; 20 | } 21 | 22 | vec2 getVec2(uint index) { 23 | float x = getVal(index); 24 | float y = getVal(index + 1); 25 | return vec2(x, y); 26 | } 27 | 28 | vec3 getVec3(uint index) { 29 | float x = getVal(index); 30 | float y = getVal(index + 1); 31 | float z = getVal(index + 2); 32 | return vec3(x, y, z); 33 | } 34 | 35 | vec3 getNormal(uint index) { 36 | vec3 p0 = getVec3(index); 37 | vec3 p1 = getVec3(index + 5); 38 | vec3 p2 = getVec3(index + 10); 39 | vec3 a = p0 - p1; 40 | vec3 b = p1 - p2; 41 | return normalize(cross(a, b)); 42 | } 43 | 44 | vec4 explode(vec4 position, vec3 normal) { 45 | float magnitude = 2.0; 46 | vec3 direction = normal * ((sin(time) + 1.0) / 2.0) * magnitude; 47 | return position + vec4(direction, 0.0); 48 | } 49 | 50 | void main() { 51 | uint index = gl_VertexID * 5; 52 | vec4 pos = vec4(getVec3(index), 1.0); 53 | tex_coords = getVec2(index + 3); 54 | 55 | uint f_index = index - index%15; 56 | vec3 normal = getNormal(f_index); 57 | pos = explode(pos, normal); 58 | gl_Position = projection * view * model * pos; 59 | 60 | } 61 | @end 62 | 63 | @fs fs 64 | in vec2 tex_coords; 65 | out vec4 frag_color; 66 | 67 | uniform sampler2D diffuse_texture; 68 | 69 | void main() { 70 | frag_color = texture(diffuse_texture, tex_coords); 71 | } 72 | @end 73 | 74 | @program phong vs fs 75 | -------------------------------------------------------------------------------- /src/4-9-geometry-shader/4-visualizing-normals.glsl: -------------------------------------------------------------------------------- 1 | @ctype mat4 hmm_mat4 2 | 3 | @block data 4 | float getVal(uint index, sampler2D texture) { 5 | float x = index % 1024; 6 | float y = index / 1024; 7 | return texelFetch(texture, ivec2(x, y), 0).r; 8 | } 9 | 10 | vec2 getVec2(uint index, sampler2D texture) { 11 | float x = getVal(index, texture); 12 | float y = getVal(index + 1, texture); 13 | return vec2(x, y); 14 | } 15 | 16 | vec3 getVec3(uint index, sampler2D texture) { 17 | float x = getVal(index, texture); 18 | float y = getVal(index + 1, texture); 19 | float z = getVal(index + 2, texture); 20 | return vec3(x, y, z); 21 | } 22 | @end 23 | 24 | @vs vs_simple 25 | @include_block data 26 | in float a_dummy; // add a dummy vertex attribute otherwise sokol complains 27 | out vec2 tex_coords; 28 | 29 | uniform vs_params { 30 | mat4 model; 31 | mat4 view; 32 | mat4 projection; 33 | }; 34 | 35 | uniform sampler2D vertex_texture; 36 | 37 | void main() { 38 | uint index = gl_VertexID * 5; 39 | vec4 pos = vec4(getVec3(index, vertex_texture), 1.0); 40 | tex_coords = getVec2(index + 3, vertex_texture); 41 | gl_Position = projection * view * model * pos; 42 | 43 | } 44 | @end 45 | 46 | @fs fs_simple 47 | in vec2 tex_coords; 48 | out vec4 frag_color; 49 | 50 | uniform sampler2D diffuse_texture; 51 | 52 | void main() { 53 | frag_color = texture(diffuse_texture, tex_coords); 54 | } 55 | @end 56 | 57 | @vs vs_normals 58 | @include_block data 59 | in float a_dummy; // add a dummy vertex attribute otherwise sokol complains 60 | 61 | uniform vs_params { 62 | mat4 model; 63 | mat4 view; 64 | mat4 projection; 65 | }; 66 | 67 | uniform sampler2D vertex_texture; 68 | 69 | const float MAGNITUDE = 0.2; 70 | 71 | vec3 getNormal(vec3 p0, vec3 p1, vec3 p2) { 72 | vec3 a = p0 - p1; 73 | vec3 b = p1 - p2; 74 | return normalize(cross(a, b)); 75 | } 76 | 77 | void main() { 78 | uint index = gl_VertexID >> 1; // divide by 2 79 | index = index * 15; 80 | 81 | vec3 p0 = getVec3(index, vertex_texture); 82 | vec3 p1 = getVec3(index + 5, vertex_texture); 83 | vec3 p2 = getVec3(index + 10, vertex_texture); 84 | 85 | vec3 mid = (p0 + p1 + p2) / 3.0; 86 | vec3 normal = getNormal(p0, p1, p2); 87 | vec3 direction = (gl_VertexID % 2) * normal; 88 | 89 | vec4 pos = vec4(mid + direction * MAGNITUDE, 1.0); 90 | gl_Position = projection * view * model * pos; 91 | } 92 | @end 93 | 94 | @fs fs_normals 95 | out vec4 frag_color; 96 | 97 | void main() { 98 | frag_color = vec4(1.0, 1.0, 0.0, 1.0); 99 | } 100 | @end 101 | 102 | @program simple vs_simple fs_simple 103 | @program normals vs_normals fs_normals 104 | -------------------------------------------------------------------------------- /src/4-9-geometry-shader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # we're using texelFetch in the shader which is not supported in glsl100 2 | if(slang STREQUAL "glsl300es:glsl100") 3 | set(slang "glsl300es") 4 | endif() 5 | 6 | fips_begin_app(4-9-1-lines windowed) 7 | fips_vs_warning_level(3) 8 | fips_files(1-lines.c) 9 | sokol_shader(1-lines.glsl ${slang}) 10 | fips_deps(sokol) 11 | fips_end_app() 12 | 13 | fips_begin_app(4-9-2-houses windowed) 14 | fips_vs_warning_level(3) 15 | fips_files(2-houses.c) 16 | sokol_shader(2-houses.glsl ${slang}) 17 | fips_deps(sokol) 18 | fips_end_app() 19 | 20 | fips_begin_app(4-9-3-exploding-object windowed) 21 | fips_vs_warning_level(3) 22 | fips_files(3-exploding-object.c) 23 | sokol_shader(3-exploding-object.glsl ${slang}) 24 | fipsutil_copy(textures-assets.yml) 25 | fips_deps(sokol) 26 | fips_end_app() 27 | 28 | fips_begin_app(4-9-4-visualizing-normals windowed) 29 | fips_vs_warning_level(3) 30 | fips_files(4-visualizing-normals.c) 31 | sokol_shader(4-visualizing-normals.glsl ${slang}) 32 | fipsutil_copy(textures-assets.yml) 33 | fips_deps(sokol) 34 | fips_end_app() -------------------------------------------------------------------------------- /src/4-9-geometry-shader/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - backpack.mtl 7 | - backpack.obj 8 | - backpack_diffuse.jpg 9 | - backpack_specular.jpg 10 | -------------------------------------------------------------------------------- /src/5-1-advanced-lighting/1-blinn-phong.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec3 a_normal; 7 | in vec2 a_tex_coords; 8 | 9 | // declare an interface block; see 'Advanced GLSL' for what these are. 10 | out INTERFACE { 11 | vec3 frag_pos; 12 | vec3 normal; 13 | vec2 tex_coords; 14 | } inter; 15 | 16 | uniform vs_params { 17 | mat4 view; 18 | mat4 projection; 19 | }; 20 | 21 | void main() { 22 | gl_Position = projection * view * vec4(a_pos, 1.0); 23 | inter.frag_pos = a_pos; 24 | inter.normal = a_normal; 25 | inter.tex_coords = a_tex_coords; 26 | } 27 | @end 28 | 29 | @fs fs 30 | in INTERFACE { 31 | vec3 frag_pos; 32 | vec3 normal; 33 | vec2 tex_coords; 34 | } inter; 35 | 36 | out vec4 frag_color; 37 | 38 | uniform fs_params { 39 | vec3 view_pos; 40 | vec3 light_pos; 41 | float blinn; // the shader cross compiler does not support bool as uniform 42 | }; 43 | 44 | uniform sampler2D floor_texture; 45 | 46 | void main() { 47 | vec3 color = texture(floor_texture, inter.tex_coords).rgb; 48 | // ambient 49 | vec3 ambient = 0.05 * color; 50 | // diffuse 51 | vec3 light_dir = normalize(light_pos - inter.frag_pos); 52 | vec3 normal = normalize(inter.normal); 53 | float diff = max(dot(light_dir, normal), 0.0); 54 | vec3 diffuse = diff * color; 55 | // specular 56 | vec3 view_dir = normalize(view_pos - inter.frag_pos); 57 | vec3 reflect_dir = reflect(-light_dir, normal); 58 | float spec = 0.0; 59 | 60 | if (blinn == 1.0) { 61 | vec3 halfway_dir = normalize(light_dir + view_dir); 62 | spec = pow(max(dot(normal, halfway_dir), 0.0), 32.0); 63 | } 64 | else { 65 | vec3 reflect_dir = reflect(-light_dir, normal); 66 | spec = pow(max(dot(view_dir, reflect_dir), 0.0), 8.0); 67 | } 68 | 69 | vec3 specular = vec3(0.3) * spec; // assuming bright white light color 70 | frag_color = vec4(ambient + diffuse + specular, 1.0); 71 | } 72 | @end 73 | 74 | @program blinn_phong vs fs 75 | -------------------------------------------------------------------------------- /src/5-1-advanced-lighting/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(5-1-1-blinn-phong windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-blinn-phong.c) 4 | sokol_shader(1-blinn-phong.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | -------------------------------------------------------------------------------- /src/5-1-advanced-lighting/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - wood.png 7 | -------------------------------------------------------------------------------- /src/5-2-gamma-correction/1-gamma-correction.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype vec4 hmm_vec4 3 | @ctype mat4 hmm_mat4 4 | 5 | @vs vs 6 | in vec3 a_pos; 7 | in vec3 a_normal; 8 | in vec2 a_tex_coords; 9 | 10 | // declare an interface block; see 'Advanced GLSL' for what these are. 11 | out INTERFACE { 12 | vec3 frag_pos; 13 | vec3 normal; 14 | vec2 tex_coords; 15 | } inter; 16 | 17 | uniform vs_params { 18 | mat4 view; 19 | mat4 projection; 20 | }; 21 | 22 | void main() { 23 | inter.frag_pos = a_pos; 24 | inter.normal = a_normal; 25 | inter.tex_coords = a_tex_coords; 26 | gl_Position = projection * view * vec4(a_pos, 1.0); 27 | } 28 | @end 29 | 30 | @fs fs 31 | in INTERFACE { 32 | vec3 frag_pos; 33 | vec3 normal; 34 | vec2 tex_coords; 35 | } inter; 36 | 37 | out vec4 frag_color; 38 | 39 | // using arrays of vec4 to avoid alignment issues with cross shader compilation 40 | uniform fs_params { 41 | vec4 light_pos[4]; 42 | vec4 light_colors[4]; 43 | vec3 view_pos; 44 | float gamma; // the shader cross compiler does not support bool as uniform 45 | }; 46 | 47 | uniform sampler2D floor_texture; 48 | 49 | vec3 blinnPhong(vec3 normal, vec3 frag_pos, vec3 light_pos, vec3 light_color) { 50 | // diffuse 51 | vec3 light_dir = normalize(light_pos - frag_pos); 52 | float diff = max(dot(light_dir, normal), 0.0); 53 | vec3 diffuse = diff * light_color; 54 | // specular 55 | vec3 view_dir = normalize(view_pos - frag_pos); 56 | vec3 reflect_dir = reflect(-light_dir, normal); 57 | float spec = 0.0; 58 | vec3 halfway_dir = normalize(light_dir + view_dir); 59 | spec = pow(max(dot(normal, halfway_dir), 0.0), 64.0); 60 | vec3 specular = spec * light_color; 61 | // simple attenuation 62 | float max_distance = 1.5; 63 | float distance = length(light_pos - frag_pos); 64 | float attenuation = 1.0 / (gamma == 1.0 ? distance * distance : distance); 65 | 66 | diffuse *= attenuation; 67 | specular *= attenuation; 68 | 69 | return diffuse + specular; 70 | } 71 | 72 | void main() { 73 | vec3 color = texture(floor_texture, inter.tex_coords).rgb; 74 | // if gamma correction is enabled we need to transform texture colors to linear space first 75 | // sokol does not support srgb as pixelformat 76 | if(gamma == 1.0) 77 | color = pow(color, vec3(2.2)); 78 | 79 | vec3 lighting = vec3(0.0); 80 | for(int i = 0; i < 4; ++i) 81 | lighting += blinnPhong(normalize(inter.normal), inter.frag_pos, light_pos[i].xyz, light_colors[i].rgb); 82 | color *= lighting; 83 | 84 | if(gamma == 1.0) 85 | color = pow(color, vec3(1.0/2.2)); 86 | frag_color = vec4(color, 1.0); 87 | } 88 | @end 89 | 90 | @program blinn_phong vs fs 91 | -------------------------------------------------------------------------------- /src/5-2-gamma-correction/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(5-2-1-gamma-correction windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-gamma-correction.c) 4 | sokol_shader(1-gamma-correction.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | -------------------------------------------------------------------------------- /src/5-2-gamma-correction/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - wood.png 7 | -------------------------------------------------------------------------------- /src/5-3-shadow-mapping/1-mapping-depth.glsl: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // float/rgba8 encoding/decoding so that we can use an RGBA8 3 | // shadow map instead of floating point render targets which might 4 | // not be supported everywhere 5 | // 6 | // http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ 7 | // 8 | 9 | @ctype mat4 hmm_mat4 10 | 11 | @vs vs_depth 12 | in vec3 a_pos; 13 | 14 | uniform vs_params { 15 | mat4 light_space_matrix; 16 | mat4 model; 17 | }; 18 | 19 | void main() { 20 | gl_Position = light_space_matrix * model * vec4(a_pos, 1.0); 21 | } 22 | @end 23 | 24 | @fs fs_depth 25 | out vec4 frag_color; 26 | 27 | vec4 encodeDepth(float v) { 28 | vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; 29 | enc = fract(enc); 30 | enc -= enc.yzww * vec4(1.0/255.0,1.0/255.0,1.0/255.0,0.0); 31 | return enc; 32 | } 33 | 34 | void main() { 35 | // sokol and webgl 1 do not support using the depth map as texture 36 | // so instead we write the depth value to the color map 37 | frag_color = encodeDepth(gl_FragCoord.z); 38 | } 39 | @end 40 | 41 | @vs vs_quad 42 | in vec3 a_pos; 43 | in vec2 a_tex_coords; 44 | out vec2 tex_coords; 45 | 46 | void main() { 47 | tex_coords = a_tex_coords; 48 | gl_Position = vec4(a_pos, 1.0); 49 | } 50 | @end 51 | 52 | @fs fs_quad 53 | out vec4 frag_color; 54 | in vec2 tex_coords; 55 | 56 | uniform sampler2D depth_map; 57 | 58 | float decodeDepth(vec4 rgba) { 59 | return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); 60 | } 61 | 62 | void main() { 63 | float depth_value = decodeDepth(texture(depth_map, tex_coords)); 64 | frag_color = vec4(vec3(depth_value), 1.0); 65 | } 66 | @end 67 | 68 | @program depth vs_depth fs_depth 69 | @program quad vs_quad fs_quad 70 | -------------------------------------------------------------------------------- /src/5-3-shadow-mapping/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(5-3-1-mapping-depth windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-mapping-depth.c) 4 | sokol_shader(1-mapping-depth.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(5-3-2-rendering-shadows windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-rendering-shadows.c) 11 | sokol_shader(2-rendering-shadows.glsl ${slang}) 12 | fipsutil_copy(textures-assets.yml) 13 | fips_deps(sokol) 14 | fips_end_app() 15 | 16 | fips_begin_app(5-3-3-improved-shadows windowed) 17 | fips_vs_warning_level(3) 18 | fips_files(3-improved-shadows.c) 19 | sokol_shader(3-improved-shadows.glsl ${slang}) 20 | fipsutil_copy(textures-assets.yml) 21 | fips_deps(sokol) 22 | fips_end_app() -------------------------------------------------------------------------------- /src/5-3-shadow-mapping/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - wood.png 7 | -------------------------------------------------------------------------------- /src/5-4-point-shadows/1-omnidirectional-depth.glsl: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // float/rgba8 encoding/decoding so that we can use an RGBA8 3 | // shadow map instead of floating point render targets which might 4 | // not be supported everywhere 5 | // 6 | // http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ 7 | // 8 | 9 | @ctype vec3 hmm_vec3 10 | @ctype mat4 hmm_mat4 11 | 12 | @block vs_params 13 | uniform vs_params { 14 | mat4 model; 15 | }; 16 | @end 17 | 18 | @vs vs_depth 19 | @include_block vs_params 20 | in vec3 a_pos; 21 | out vec4 frag_pos; 22 | 23 | uniform vs_params_depth { 24 | mat4 light_space_matrix; 25 | }; 26 | 27 | void main() { 28 | frag_pos = model * vec4(a_pos, 1.0); 29 | gl_Position = light_space_matrix * frag_pos; 30 | } 31 | @end 32 | 33 | @fs fs_depth 34 | in vec4 frag_pos; 35 | out vec4 frag_color; 36 | 37 | uniform fs_params_depth { 38 | vec3 light_pos; 39 | float far_plane; 40 | }; 41 | 42 | vec4 encodeDepth(float v) { 43 | vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; 44 | enc = fract(enc); 45 | enc -= enc.yzww * vec4(1.0/255.0,1.0/255.0,1.0/255.0,0.0); 46 | return enc; 47 | } 48 | 49 | void main() { 50 | float light_distance = length(frag_pos.xyz - light_pos); 51 | 52 | // map to [0;1] range by dividing by far_plane 53 | light_distance = light_distance / far_plane; 54 | 55 | // write this as modified depth 56 | // sokol and webgl 1 do not support using the depth map as texture 57 | // so instead we write the depth value to the color map 58 | frag_color = encodeDepth(light_distance); 59 | } 60 | @end 61 | 62 | @vs vs_shadows 63 | @include_block vs_params 64 | in vec3 a_pos; 65 | in vec3 a_normal; 66 | in vec2 a_tex_coords; 67 | 68 | out INTERFACE { 69 | vec3 frag_pos; 70 | } inter; 71 | 72 | uniform vs_params_shadows { 73 | mat4 projection; 74 | mat4 view; 75 | }; 76 | 77 | void main() { 78 | inter.frag_pos = vec3(model * vec4(a_pos, 1.0)); 79 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 80 | } 81 | @end 82 | 83 | @fs fs_shadows 84 | in INTERFACE { 85 | vec3 frag_pos; 86 | } inter; 87 | 88 | out vec4 frag_color; 89 | 90 | uniform samplerCube depth_map; 91 | 92 | uniform fs_params_shadows { 93 | vec3 light_pos; 94 | float far_plane; 95 | }; 96 | 97 | float decodeDepth(vec4 rgba) { 98 | return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); 99 | } 100 | 101 | vec3 shadowCalculation(vec3 frag_pos) { 102 | // get vector between fragment position and light position 103 | vec3 frag_to_light = frag_pos - light_pos; 104 | // use the fragment to light vector to sample from the depth map 105 | float closest_depth = decodeDepth(texture(depth_map, frag_to_light)); 106 | // it is currently in linear range between [0,1], let's re-transform it back to original depth value 107 | closest_depth *= far_plane; 108 | // now get current linear depth as the length between the fragment and light position 109 | float current_depth = length(frag_to_light); 110 | // test for shadows 111 | float bias = 0.05; // we use a much larger bias since depth is now in [near_plane, far_plane] range 112 | float shadow = current_depth - bias > closest_depth ? 1.0 : 0.0; 113 | 114 | // display closest_depth as debug (to visualize depth cubemap) 115 | return vec3(closest_depth / far_plane); 116 | 117 | // return shadow; 118 | } 119 | 120 | void main() { 121 | // calculate shadow 122 | frag_color = vec4(shadowCalculation(inter.frag_pos), 1.0); 123 | } 124 | @end 125 | 126 | @program depth vs_depth fs_depth 127 | @program shadows vs_shadows fs_shadows 128 | -------------------------------------------------------------------------------- /src/5-4-point-shadows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(5-4-1-omnidirectional-depth windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-omnidirectional-depth.c) 4 | sokol_shader(1-omnidirectional-depth.glsl ${slang}) 5 | fips_deps(sokol) 6 | fips_end_app() 7 | 8 | fips_begin_app(5-4-2-omnidirectional-shadows windowed) 9 | fips_vs_warning_level(3) 10 | fips_files(2-omnidirectional-shadows.c) 11 | sokol_shader(2-omnidirectional-shadows.glsl ${slang}) 12 | fipsutil_copy(textures-assets.yml) 13 | fips_deps(sokol) 14 | fips_end_app() 15 | 16 | fips_begin_app(5-4-3-omnidirectional-PCF windowed) 17 | fips_vs_warning_level(3) 18 | fips_files(3-omnidirectional-PCF.c) 19 | sokol_shader(3-omnidirectional-PCF.glsl ${slang}) 20 | fipsutil_copy(textures-assets.yml) 21 | fips_deps(sokol) 22 | fips_end_app() -------------------------------------------------------------------------------- /src/5-4-point-shadows/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - wood.png 7 | -------------------------------------------------------------------------------- /src/5-5-normal-mapping/1-normal-mapping.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec3 a_normal; 7 | in vec2 a_tex_coords; 8 | 9 | // declare an interface block; see 'Advanced GLSL' for what these are. 10 | out INTERFACE { 11 | vec3 frag_pos; 12 | vec3 normal; 13 | vec2 tex_coords; 14 | } inter; 15 | 16 | uniform vs_params { 17 | mat4 view; 18 | mat4 projection; 19 | }; 20 | 21 | void main() { 22 | gl_Position = projection * view * vec4(a_pos, 1.0); 23 | inter.frag_pos = a_pos; 24 | inter.normal = a_normal; 25 | inter.tex_coords = a_tex_coords; 26 | } 27 | @end 28 | 29 | @fs fs 30 | in INTERFACE { 31 | vec3 frag_pos; 32 | vec3 normal; 33 | vec2 tex_coords; 34 | } inter; 35 | 36 | out vec4 frag_color; 37 | 38 | uniform fs_params { 39 | vec3 view_pos; 40 | vec3 light_pos; 41 | float normal_mapping; // the shader cross compiler does not support bool as uniform 42 | }; 43 | 44 | uniform sampler2D diffuse_map; 45 | uniform sampler2D normal_map; 46 | 47 | void main() { 48 | vec3 color = texture(diffuse_map, inter.tex_coords).rgb; 49 | // ambient 50 | vec3 ambient = 0.05 * color; 51 | // diffuse 52 | vec3 light_dir = normalize(light_pos - inter.frag_pos); 53 | // obtain normal from normal map in range [0,1] 54 | vec3 normal = texture(normal_map, inter.tex_coords).rgb; 55 | // transform normal vector to range [-1,1] 56 | normal = normalize(normal * 2.0 - 1.0); 57 | normal = normal_mapping == 1.0 ? normal : normalize(inter.normal); 58 | float diff = max(dot(light_dir, normal), 0.0); 59 | vec3 diffuse = diff * color; 60 | // specular 61 | vec3 view_dir = normalize(view_pos - inter.frag_pos); 62 | vec3 reflect_dir = reflect(-light_dir, normal); 63 | vec3 halfway_dir = normalize(light_dir + view_dir); 64 | float spec = pow(max(dot(normal, halfway_dir), 0.0), 32.0); 65 | vec3 specular = vec3(0.3) * spec; // assuming bright white light color 66 | frag_color = vec4(ambient + diffuse + specular, 1.0); 67 | } 68 | @end 69 | 70 | @program blinn_phong vs fs 71 | -------------------------------------------------------------------------------- /src/5-5-normal-mapping/2-tangent-space.glsl: -------------------------------------------------------------------------------- 1 | @ctype vec3 hmm_vec3 2 | @ctype mat4 hmm_mat4 3 | 4 | @vs vs 5 | in vec3 a_pos; 6 | in vec3 a_normal; 7 | in vec2 a_tex_coords; 8 | in vec3 a_tangent; 9 | 10 | out INTERFACE { 11 | vec2 tex_coords; 12 | vec3 tangent_light_pos; 13 | vec3 tangent_view_pos; 14 | vec3 tangent_frag_pos; 15 | } inter; 16 | 17 | uniform vs_params { 18 | mat4 view; 19 | mat4 projection; 20 | mat4 model; 21 | vec3 light_pos; 22 | vec3 view_pos; 23 | }; 24 | 25 | mat3 transpose(mat3 mat) { 26 | vec3 i0 = mat[0]; 27 | vec3 i1 = mat[1]; 28 | vec3 i2 = mat[2]; 29 | 30 | return mat3( 31 | vec3(i0.x, i1.x, i2.x), 32 | vec3(i0.y, i1.y, i2.y), 33 | vec3(i0.z, i1.z, i2.z) 34 | ); 35 | } 36 | 37 | void main() { 38 | inter.tex_coords = a_tex_coords; 39 | 40 | // inverse tranpose is left out because: 41 | // (a) glsl es 1.0 (webgl 1.0) doesn't have inverse and transpose functions 42 | // (b) we're not performing non-uniform scale 43 | mat3 normal_matrix = mat3(model); 44 | vec3 T = normalize(normal_matrix * a_tangent); 45 | vec3 N = normalize(normal_matrix * a_normal); 46 | // re-orthogonalize T with respect to N 47 | T = normalize(T - dot(T, N) * N); 48 | // then retrieve perpendicular vector B with the cross product of T and N 49 | vec3 B = cross(N, T); 50 | 51 | mat3 TBN = transpose(mat3(T, B, N)); 52 | inter.tangent_light_pos = TBN * light_pos; 53 | inter.tangent_view_pos = TBN * view_pos; 54 | inter.tangent_frag_pos = TBN * vec3(model * vec4(a_pos, 1.0)); 55 | 56 | gl_Position = projection * view * model * vec4(a_pos, 1.0); 57 | } 58 | @end 59 | 60 | @fs fs 61 | in INTERFACE { 62 | vec2 tex_coords; 63 | vec3 tangent_light_pos; 64 | vec3 tangent_view_pos; 65 | vec3 tangent_frag_pos; 66 | } inter; 67 | 68 | out vec4 frag_color; 69 | 70 | uniform sampler2D diffuse_map; 71 | uniform sampler2D normal_map; 72 | 73 | void main() { 74 | // obtain normal from normal map in range [0,1] 75 | vec3 normal = texture(normal_map, inter.tex_coords).rgb; 76 | // transform normal vector to range [-1,1] 77 | normal = normalize(normal * 2.0 - 1.0); // this normal is in tangent space 78 | 79 | // get diffuse color 80 | vec3 color = texture(diffuse_map, inter.tex_coords).rgb; 81 | // ambient 82 | vec3 ambient = 0.1 * color; 83 | // diffuse 84 | vec3 light_dir = normalize(inter.tangent_light_pos - inter.tangent_frag_pos); 85 | float diff = max(dot(light_dir, normal), 0.0); 86 | vec3 diffuse = diff * color; 87 | // specular 88 | vec3 view_dir = normalize(inter.tangent_view_pos - inter.tangent_frag_pos); 89 | vec3 reflect_dir = reflect(-light_dir, normal); 90 | vec3 halfway_dir = normalize(light_dir + view_dir); 91 | float spec = pow(max(dot(normal, halfway_dir), 0.0), 32.0); 92 | 93 | vec3 specular = vec3(0.2) * spec; 94 | frag_color = vec4(ambient + diffuse + specular, 1.0); 95 | } 96 | @end 97 | 98 | @program blinn_phong vs fs 99 | -------------------------------------------------------------------------------- /src/5-5-normal-mapping/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | fips_begin_app(5-5-1-normal-mapping windowed) 2 | fips_vs_warning_level(3) 3 | fips_files(1-normal-mapping.c) 4 | sokol_shader(1-normal-mapping.glsl ${slang}) 5 | fipsutil_copy(textures-assets.yml) 6 | fips_deps(sokol) 7 | fips_end_app() 8 | 9 | fips_begin_app(5-5-2-tangent-space windowed) 10 | fips_vs_warning_level(3) 11 | fips_files(2-tangent-space.c) 12 | sokol_shader(2-tangent-space.glsl ${slang}) 13 | fipsutil_copy(textures-assets.yml) 14 | fips_deps(sokol) 15 | fips_end_app() 16 | 17 | fips_begin_app(5-5-3-complex-object windowed) 18 | fips_vs_warning_level(3) 19 | fips_files(3-complex-object.c) 20 | sokol_shader(3-complex-object.glsl ${slang}) 21 | fipsutil_copy(textures-assets.yml) 22 | fips_deps(sokol) 23 | fips_end_app() 24 | -------------------------------------------------------------------------------- /src/5-5-normal-mapping/textures-assets.yml: -------------------------------------------------------------------------------- 1 | --- 2 | options: 3 | src_dir: ../data 4 | 5 | files: 6 | - brickwall.jpg 7 | - brickwall_normal.jpg 8 | - backpack.mtl 9 | - backpack.obj 10 | - backpack_diffuse.jpg 11 | - backpack_specular.jpg 12 | - backpack_normal.png -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # select the 3D backend for sokol_gfx.h and sokol_app.h 2 | # the sokol_config() macro is in the top-level CMakeLists.txt file! 3 | sokol_config() 4 | 5 | fips_ide_group(Src/1-3-hello-window) 6 | add_subdirectory(1-3-hello-window) 7 | fips_ide_group(Src/1-4-hello-triangle) 8 | add_subdirectory(1-4-hello-triangle) 9 | fips_ide_group(Src/1-5-shaders) 10 | add_subdirectory(1-5-shaders) 11 | fips_ide_group(Src/1-6-textures) 12 | add_subdirectory(1-6-textures) 13 | fips_ide_group(Src/1-7-transformations) 14 | add_subdirectory(1-7-transformations) 15 | fips_ide_group(Src/1-8-coordinate-systems) 16 | add_subdirectory(1-8-coordinate-systems) 17 | fips_ide_group(Src/1-9-camera) 18 | add_subdirectory(1-9-camera) 19 | fips_ide_group(Src/2-1-colors) 20 | add_subdirectory(2-1-colors) 21 | fips_ide_group(Src/2-2-basic-lighting) 22 | add_subdirectory(2-2-basic-lighting) 23 | fips_ide_group(Src/2-3-materials) 24 | add_subdirectory(2-3-materials) 25 | fips_ide_group(Src/2-4-lighting-maps) 26 | add_subdirectory(2-4-lighting-maps) 27 | fips_ide_group(Src/2-5-light-casters) 28 | add_subdirectory(2-5-light-casters) 29 | fips_ide_group(Src/2-6-multiple-lights) 30 | add_subdirectory(2-6-multiple-lights) 31 | fips_ide_group(Src/3-1-model) 32 | add_subdirectory(3-1-model) 33 | fips_ide_group(Src/4-1-depth-testing) 34 | add_subdirectory(4-1-depth-testing) 35 | fips_ide_group(Src/4-2-stencil-testing) 36 | add_subdirectory(4-2-stencil-testing) 37 | fips_ide_group(Src/4-3-blending) 38 | add_subdirectory(4-3-blending) 39 | fips_ide_group(Src/4-4-face-culling) 40 | add_subdirectory(4-4-face-culling) 41 | fips_ide_group(Src/4-5-framebuffers) 42 | add_subdirectory(4-5-framebuffers) 43 | fips_ide_group(Src/4-6-cubemaps) 44 | add_subdirectory(4-6-cubemaps) 45 | fips_ide_group(Src/4-8-advanced-glsl) 46 | add_subdirectory(4-8-advanced-glsl) 47 | fips_ide_group(Src/4-9-geometry-shader) 48 | add_subdirectory(4-9-geometry-shader) 49 | fips_ide_group(Src/4-10-instancing) 50 | add_subdirectory(4-10-instancing) 51 | fips_ide_group(Src/4-11-anti-aliasing) 52 | add_subdirectory(4-11-anti-aliasing) 53 | fips_ide_group(Src/5-1-advanced-lighting) 54 | add_subdirectory(5-1-advanced-lighting) 55 | fips_ide_group(Src/5-2-gamma-correction) 56 | add_subdirectory(5-2-gamma-correction) 57 | fips_ide_group(Src/5-3-shadow-mapping) 58 | add_subdirectory(5-3-shadow-mapping) 59 | fips_ide_group(Src/5-4-point-shadows) 60 | add_subdirectory(5-4-point-shadows) 61 | fips_ide_group(Src/5-5-normal-mapping) 62 | add_subdirectory(5-5-normal-mapping) 63 | -------------------------------------------------------------------------------- /src/data/awesomeface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/awesomeface.png -------------------------------------------------------------------------------- /src/data/backpack.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Scene_-_Root 5 | Ns 225.000000 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.800000 0.800000 0.800000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.0 0.0 0.0 10 | Ni 1.450000 11 | d 1.000000 12 | illum 2 13 | map_Kd backpack_diffuse.jpg 14 | map_Bump backpack_normal.png 15 | map_Ks backpack_specular.jpg 16 | 17 | -------------------------------------------------------------------------------- /src/data/backpack_diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/backpack_diffuse.jpg -------------------------------------------------------------------------------- /src/data/backpack_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/backpack_normal.png -------------------------------------------------------------------------------- /src/data/backpack_specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/backpack_specular.jpg -------------------------------------------------------------------------------- /src/data/brickwall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/brickwall.jpg -------------------------------------------------------------------------------- /src/data/brickwall_normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/brickwall_normal.jpg -------------------------------------------------------------------------------- /src/data/container.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/container.jpg -------------------------------------------------------------------------------- /src/data/container2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/container2.png -------------------------------------------------------------------------------- /src/data/container2_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/container2_specular.png -------------------------------------------------------------------------------- /src/data/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/grass.png -------------------------------------------------------------------------------- /src/data/marble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/marble.jpg -------------------------------------------------------------------------------- /src/data/mars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/mars.png -------------------------------------------------------------------------------- /src/data/metal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/metal.png -------------------------------------------------------------------------------- /src/data/planet.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Mars 5 | Ns 96.078443 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.0 0.0 0.0 10 | Ni 1.000000 11 | d 1.000000 12 | illum 2 13 | map_Kd mars.png 14 | -------------------------------------------------------------------------------- /src/data/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 | -------------------------------------------------------------------------------- /src/data/rock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/rock.png -------------------------------------------------------------------------------- /src/data/skybox_back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/skybox_back.jpg -------------------------------------------------------------------------------- /src/data/skybox_bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/skybox_bottom.jpg -------------------------------------------------------------------------------- /src/data/skybox_front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/skybox_front.jpg -------------------------------------------------------------------------------- /src/data/skybox_left.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/skybox_left.jpg -------------------------------------------------------------------------------- /src/data/skybox_right.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/skybox_right.jpg -------------------------------------------------------------------------------- /src/data/skybox_top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/skybox_top.jpg -------------------------------------------------------------------------------- /src/data/transparent_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/transparent_window.png -------------------------------------------------------------------------------- /src/data/uv_grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/uv_grid.png -------------------------------------------------------------------------------- /src/data/wood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/src/data/wood.png -------------------------------------------------------------------------------- /webpage/1-3-1-rendering.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-3-1-rendering.jpg -------------------------------------------------------------------------------- /webpage/1-4-1-triangle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-4-1-triangle.jpg -------------------------------------------------------------------------------- /webpage/1-4-2-quad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-4-2-quad.jpg -------------------------------------------------------------------------------- /webpage/1-4-3-quad-wireframe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-4-3-quad-wireframe.jpg -------------------------------------------------------------------------------- /webpage/1-5-1-in-out.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-5-1-in-out.jpg -------------------------------------------------------------------------------- /webpage/1-5-2-uniforms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-5-2-uniforms.jpg -------------------------------------------------------------------------------- /webpage/1-5-3-attributes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-5-3-attributes.jpg -------------------------------------------------------------------------------- /webpage/1-6-1-texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-6-1-texture.jpg -------------------------------------------------------------------------------- /webpage/1-6-2-texture-blend.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-6-2-texture-blend.jpg -------------------------------------------------------------------------------- /webpage/1-6-3-multiple-textures.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-6-3-multiple-textures.jpg -------------------------------------------------------------------------------- /webpage/1-7-1-scale-rotate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-7-1-scale-rotate.jpg -------------------------------------------------------------------------------- /webpage/1-7-2-rotate-translate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-7-2-rotate-translate.jpg -------------------------------------------------------------------------------- /webpage/1-8-1-plane.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-8-1-plane.jpg -------------------------------------------------------------------------------- /webpage/1-8-2-cube.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-8-2-cube.jpg -------------------------------------------------------------------------------- /webpage/1-8-3-more-cubes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-8-3-more-cubes.jpg -------------------------------------------------------------------------------- /webpage/1-9-1-lookat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-9-1-lookat.jpg -------------------------------------------------------------------------------- /webpage/1-9-2-walk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-9-2-walk.jpg -------------------------------------------------------------------------------- /webpage/1-9-3-look.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/1-9-3-look.jpg -------------------------------------------------------------------------------- /webpage/2-1-1-scene.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-1-1-scene.jpg -------------------------------------------------------------------------------- /webpage/2-2-1-ambient.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-2-1-ambient.jpg -------------------------------------------------------------------------------- /webpage/2-2-2-diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-2-2-diffuse.jpg -------------------------------------------------------------------------------- /webpage/2-2-3-specular.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-2-3-specular.jpg -------------------------------------------------------------------------------- /webpage/2-3-1-material.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-3-1-material.jpg -------------------------------------------------------------------------------- /webpage/2-3-2-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-3-2-light.jpg -------------------------------------------------------------------------------- /webpage/2-3-3-light-colors.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-3-3-light-colors.jpg -------------------------------------------------------------------------------- /webpage/2-4-1-diffuse-map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-4-1-diffuse-map.jpg -------------------------------------------------------------------------------- /webpage/2-4-2-specular-map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-4-2-specular-map.jpg -------------------------------------------------------------------------------- /webpage/2-5-1-directional-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-5-1-directional-light.jpg -------------------------------------------------------------------------------- /webpage/2-5-2-point-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-5-2-point-light.jpg -------------------------------------------------------------------------------- /webpage/2-5-3-spot-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-5-3-spot-light.jpg -------------------------------------------------------------------------------- /webpage/2-5-4-soft-spot-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-5-4-soft-spot-light.jpg -------------------------------------------------------------------------------- /webpage/2-6-1-combined-lights.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/2-6-1-combined-lights.jpg -------------------------------------------------------------------------------- /webpage/3-1-1-backpack-diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/3-1-1-backpack-diffuse.jpg -------------------------------------------------------------------------------- /webpage/3-1-2-backpack-lights.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/3-1-2-backpack-lights.jpg -------------------------------------------------------------------------------- /webpage/4-1-1-depth-always.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-1-1-depth-always.jpg -------------------------------------------------------------------------------- /webpage/4-1-2-depth-less.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-1-2-depth-less.jpg -------------------------------------------------------------------------------- /webpage/4-1-3-depth-buffer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-1-3-depth-buffer.jpg -------------------------------------------------------------------------------- /webpage/4-1-4-linear-depth-buffer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-1-4-linear-depth-buffer.jpg -------------------------------------------------------------------------------- /webpage/4-10-1-instancing.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-10-1-instancing.jpg -------------------------------------------------------------------------------- /webpage/4-10-2-instanced-arrays.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-10-2-instanced-arrays.jpg -------------------------------------------------------------------------------- /webpage/4-10-3-asteroid-field.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-10-3-asteroid-field.jpg -------------------------------------------------------------------------------- /webpage/4-10-4-asteroid-field-instanced.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-10-4-asteroid-field-instanced.jpg -------------------------------------------------------------------------------- /webpage/4-11-1-msaa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-11-1-msaa.jpg -------------------------------------------------------------------------------- /webpage/4-11-2-offscreen-msaa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-11-2-offscreen-msaa.jpg -------------------------------------------------------------------------------- /webpage/4-11-3-grayscale-msaa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-11-3-grayscale-msaa.jpg -------------------------------------------------------------------------------- /webpage/4-2-1-object-outlining.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-2-1-object-outlining.jpg -------------------------------------------------------------------------------- /webpage/4-3-1-grass-opaque.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-3-1-grass-opaque.jpg -------------------------------------------------------------------------------- /webpage/4-3-2-grass-transparent.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-3-2-grass-transparent.jpg -------------------------------------------------------------------------------- /webpage/4-3-3-blending.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-3-3-blending.jpg -------------------------------------------------------------------------------- /webpage/4-3-4-blending-sorted.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-3-4-blending-sorted.jpg -------------------------------------------------------------------------------- /webpage/4-4-1-cull-front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-4-1-cull-front.jpg -------------------------------------------------------------------------------- /webpage/4-5-1-render-to-texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-5-1-render-to-texture.jpg -------------------------------------------------------------------------------- /webpage/4-5-2-inversion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-5-2-inversion.jpg -------------------------------------------------------------------------------- /webpage/4-5-3-grayscale.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-5-3-grayscale.jpg -------------------------------------------------------------------------------- /webpage/4-5-4-sharpen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-5-4-sharpen.jpg -------------------------------------------------------------------------------- /webpage/4-5-5-blur.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-5-5-blur.jpg -------------------------------------------------------------------------------- /webpage/4-5-6-edge-detection.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-5-6-edge-detection.jpg -------------------------------------------------------------------------------- /webpage/4-6-1-skybox.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-6-1-skybox.jpg -------------------------------------------------------------------------------- /webpage/4-6-2-reflection-cube.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-6-2-reflection-cube.jpg -------------------------------------------------------------------------------- /webpage/4-6-3-reflection-backpack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-6-3-reflection-backpack.jpg -------------------------------------------------------------------------------- /webpage/4-6-4-refraction-cube.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-6-4-refraction-cube.jpg -------------------------------------------------------------------------------- /webpage/4-6-5-refraction-backpack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-6-5-refraction-backpack.jpg -------------------------------------------------------------------------------- /webpage/4-8-1-point-size.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-8-1-point-size.jpg -------------------------------------------------------------------------------- /webpage/4-8-2-frag-coord.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-8-2-frag-coord.jpg -------------------------------------------------------------------------------- /webpage/4-8-3-front-facing.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-8-3-front-facing.jpg -------------------------------------------------------------------------------- /webpage/4-8-4-uniform-buffers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-8-4-uniform-buffers.jpg -------------------------------------------------------------------------------- /webpage/4-9-1-lines.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-9-1-lines.jpg -------------------------------------------------------------------------------- /webpage/4-9-2-houses.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-9-2-houses.jpg -------------------------------------------------------------------------------- /webpage/4-9-3-exploding-object.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-9-3-exploding-object.jpg -------------------------------------------------------------------------------- /webpage/4-9-4-visualizing-normals.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/4-9-4-visualizing-normals.jpg -------------------------------------------------------------------------------- /webpage/5-1-1-blinn-phong.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-1-1-blinn-phong.jpg -------------------------------------------------------------------------------- /webpage/5-2-1-gamma-correction.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-2-1-gamma-correction.jpg -------------------------------------------------------------------------------- /webpage/5-3-1-mapping-depth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-3-1-mapping-depth.jpg -------------------------------------------------------------------------------- /webpage/5-3-2-rendering-shadows.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-3-2-rendering-shadows.jpg -------------------------------------------------------------------------------- /webpage/5-3-3-improved-shadows.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-3-3-improved-shadows.jpg -------------------------------------------------------------------------------- /webpage/5-4-1-omnidirectional-depth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-4-1-omnidirectional-depth.jpg -------------------------------------------------------------------------------- /webpage/5-4-2-omnidirectional-shadows.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-4-2-omnidirectional-shadows.jpg -------------------------------------------------------------------------------- /webpage/5-4-3-omnidirectional-PCF.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-4-3-omnidirectional-PCF.jpg -------------------------------------------------------------------------------- /webpage/5-5-1-normal-mapping.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-5-1-normal-mapping.jpg -------------------------------------------------------------------------------- /webpage/5-5-2-tangent-space.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-5-2-tangent-space.jpg -------------------------------------------------------------------------------- /webpage/5-5-3-complex-object.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/5-5-3-complex-object.jpg -------------------------------------------------------------------------------- /webpage/dummy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/dummy.jpg -------------------------------------------------------------------------------- /webpage/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/favicon.png -------------------------------------------------------------------------------- /webpage/fontello.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/fontello.woff -------------------------------------------------------------------------------- /webpage/fontello.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeertArien/learnopengl-examples/8f80669ea7a55b5d68324fc9b8598ea23393ca9a/webpage/fontello.woff2 -------------------------------------------------------------------------------- /webpage/shell.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Emscripten-Generated Code 7 | 29 | 30 | 31 | 32 | 62 | {{{ SCRIPT }}} 63 | 64 | 65 | -------------------------------------------------------------------------------- /webpage/wasm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ${name} 6 | 7 | 55 | 56 | 57 |
${name} 58 | home 59 | src 60 | glsl 61 |
62 | 63 | 89 | 90 | 91 | 92 | --------------------------------------------------------------------------------