├── .github ├── dependabot.yml └── workflows │ └── ci.yaml ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE ├── NEXT.md ├── README.md ├── docs ├── design.md ├── imgs │ ├── 01-screenshot.png │ ├── 02-screenshot-alt.png │ ├── 02-screenshot-alt2.png │ ├── 02-screenshot.png │ ├── 03-screenshot-alt.png │ ├── 03-screenshot-alt2.png │ ├── 03-screenshot.png │ ├── 04-screenshot-alt.png │ ├── 04-screenshot.png │ ├── 05-screenshot.png │ ├── 08-screenshot-alt.png │ ├── 08-screenshot.png │ ├── 10-screenshot.png │ ├── displacement_map.gif │ ├── luminance.svg │ └── luminance_alt.svg ├── renaming.md └── strongly_typed_color_slots.md ├── examples ├── README.md ├── common │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ └── src │ │ ├── adapt-vs.glsl │ │ ├── attributeless-vs.glsl │ │ ├── attributeless.rs │ │ ├── copy-fs.glsl │ │ ├── copy-multi-fs.glsl │ │ ├── copy-vs.glsl │ │ ├── cubemap-viewer-fs.glsl │ │ ├── cubemap-viewer-vs.glsl │ │ ├── displacement-fs.glsl │ │ ├── displacement-map-resources │ │ ├── displacement-map-fs.glsl │ │ ├── displacement-map-vs.glsl │ │ ├── displacement_1.png │ │ └── displacement_2.png │ │ ├── displacement-vs.glsl │ │ ├── displacement_map.rs │ │ ├── dynamic_uniform_interface.rs │ │ ├── env-mapping-fs.glsl │ │ ├── env-mapping-vs.glsl │ │ ├── funtest_360_manually_drop_framebuffer.rs │ │ ├── funtest_483_indices_mut_corruption.rs │ │ ├── funtest_flatten_slice.rs │ │ ├── funtest_gl33_f64_uniform.rs │ │ ├── funtest_pixel_array_encoding.rs │ │ ├── funtest_scissor_test.rs │ │ ├── funtest_tess_no_data.rs │ │ ├── hello_world.rs │ │ ├── hello_world_more.rs │ │ ├── instancing-fs.glsl │ │ ├── instancing-vs.glsl │ │ ├── interactive_triangle.rs │ │ ├── lib.rs │ │ ├── mrt.rs │ │ ├── multi-fs.glsl │ │ ├── offscreen.rs │ │ ├── polymorphic_hello_world.rs │ │ ├── query_info.rs │ │ ├── query_texture_texels.rs │ │ ├── render_state.rs │ │ ├── shader_uniform_adapt.rs │ │ ├── shader_uniforms.rs │ │ ├── shared.rs │ │ ├── simple-fs.glsl │ │ ├── simple-vs.glsl │ │ ├── skybox.rs │ │ ├── sliced_vertex_entity.rs │ │ ├── stencil.rs │ │ ├── texture-fs.glsl │ │ ├── texture-vs.glsl │ │ ├── texture.rs │ │ ├── uni-buffer-2d-vs.glsl │ │ ├── uni_buffer.rs │ │ └── vertex_instancing.rs ├── desktop │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ └── src │ │ ├── main.rs │ │ └── platform.rs └── web │ ├── .cargo │ └── config.toml │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ ├── index.js │ ├── package.json │ ├── src │ ├── lib.rs │ └── platform.rs │ └── webpack.config.js ├── luminance-derive ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── attrib.rs │ ├── lib.rs │ ├── memory_layout.rs │ ├── render_slots.rs │ ├── uniforms.rs │ └── vertex.rs ├── luminance-front ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── context.rs │ ├── framebuffer.rs │ ├── lib.rs │ ├── pipeline.rs │ ├── query.rs │ ├── render_gate.rs │ ├── shader.rs │ ├── shader │ └── types.rs │ ├── shading_gate.rs │ ├── tess.rs │ ├── tess_gate.rs │ └── texture.rs ├── luminance-gl ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── gl33.rs │ ├── gl33 │ ├── buffer.rs │ ├── depth_stencil.rs │ ├── framebuffer.rs │ ├── pipeline.rs │ ├── pixel.rs │ ├── query.rs │ ├── shader.rs │ ├── state.rs │ ├── tess.rs │ ├── texture.rs │ └── vertex_restart.rs │ └── lib.rs ├── luminance-gl2 ├── Cargo.toml └── src │ ├── gl33.rs │ ├── lib.rs │ └── log.rs ├── luminance-glfw ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ └── lib.rs ├── luminance-glutin ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ └── lib.rs ├── luminance-sdl2 ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ └── lib.rs ├── luminance-std140 ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ └── lib.rs ├── luminance-web-sys ├── .cargo │ └── config.toml ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ └── lib.rs ├── luminance-webgl ├── .cargo │ └── config.toml ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md └── src │ ├── lib.rs │ ├── slice.rs │ ├── webgl2.rs │ └── webgl2 │ ├── array_buffer.rs │ ├── buffer.rs │ ├── framebuffer.rs │ ├── pipeline.rs │ ├── pixel.rs │ ├── query.rs │ ├── shader.rs │ ├── state.rs │ ├── tess.rs │ └── texture.rs ├── luminance ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md ├── src │ ├── backend.rs │ ├── blending.rs │ ├── context.rs │ ├── depth_stencil.rs │ ├── dim.rs │ ├── face_culling.rs │ ├── framebuffer.rs │ ├── has_field.rs │ ├── lib.rs │ ├── named_index.rs │ ├── pipeline.rs │ ├── pixel.rs │ ├── primitive.rs │ ├── query.rs │ ├── render_slots.rs │ ├── render_state.rs │ ├── scissor.rs │ ├── shader.rs │ ├── shader │ │ └── types.rs │ ├── texture.rs │ ├── vertex.rs │ ├── vertex_entity.rs │ └── vertex_storage.rs └── tests │ ├── derive_memory_layout.rs │ ├── derive_render_slots.rs │ ├── uniform_interface.rs │ └── vertex.rs ├── rustfmt.toml └── scripts └── rollout /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | versioning-strategy: widen 5 | directory: "/." 6 | schedule: 7 | interval: daily 8 | time: "04:00" 9 | open-pull-requests-limit: 10 10 | target-branch: master 11 | reviewers: 12 | - phaazon 13 | assignees: 14 | - phaazon 15 | labels: 16 | - dependency-update 17 | ignore: 18 | - dependency-name: glutin 19 | versions: 20 | - 0.26.0 21 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [pull_request] 3 | 4 | jobs: 5 | build-linux: 6 | strategy: 7 | matrix: 8 | rustc: ["nightly"] 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Install dependencies 12 | run: | 13 | sudo apt-get update 14 | sudo apt-get install -y libxrandr-dev xorg-dev libsdl2-dev 15 | - uses: actions/checkout@v2 16 | - name: Build 17 | run: | 18 | rustup default ${{ matrix.rustc }} 19 | cargo build 20 | cargo test 21 | 22 | build-windows: 23 | strategy: 24 | matrix: 25 | rustc: ["nightly"] 26 | runs-on: windows-latest 27 | steps: 28 | - uses: actions/checkout@v2 29 | - name: Build 30 | run: | 31 | rustup default ${{ matrix.rustc }} 32 | cargo build 33 | cargo test 34 | 35 | build-macosx: 36 | strategy: 37 | matrix: 38 | rustc: ["nightly"] 39 | runs-on: macOS-latest 40 | steps: 41 | - name: Install dependencies 42 | run: brew install SDL2 43 | - uses: actions/checkout@v2 44 | - name: Build 45 | run: | 46 | rustup default ${{ matrix.rustc }} 47 | cargo build 48 | cargo test 49 | 50 | # build-wasm: 51 | # strategy: 52 | # matrix: 53 | # rustc: ["nightly"] 54 | # runs-on: ubuntu-latest 55 | # steps: 56 | # - name: Install rustup WASM toolchain 57 | # run: | 58 | # rustup default ${{ matrix.rustc }} 59 | # rustup target install wasm32-unknown-unknown 60 | # - uses: actions/checkout@v2 61 | # - name: Build 62 | # run: | 63 | # cd $GITHUB_WORKSPACE/luminance-webgl 64 | # cargo build 65 | # cd $GITHUB_WORKSPACE/luminance-web-sys 66 | # cargo build 67 | # cd $GITHUB_WORKSPACE/examples/web 68 | # yarn install 69 | # yarn build 70 | 71 | # functional-tests-desktop: 72 | # strategy: 73 | # matrix: 74 | # rustc: ["nightly"] 75 | # runs-on: ubuntu-latest 76 | # steps: 77 | # - name: Install dependencies 78 | # run: | 79 | # sudo apt-get update 80 | # sudo apt-get install -y libxrandr-dev xorg-dev libsdl2-dev 81 | # - uses: actions/checkout@v2 82 | # - name: Functional testing 83 | # run: | 84 | # rustup default ${{ matrix.rustc }} 85 | # cd examples/desktop 86 | # cargo check --features funtest,funtest-gl33-f64-uniform 87 | # 88 | # functional-tests-web: 89 | # strategy: 90 | # matrix: 91 | # rustc: ["nightly"] 92 | # runs-on: ubuntu-latest 93 | # steps: 94 | # - name: Install rustup WASM toolchain 95 | # run: | 96 | # rustup default ${{ matrix.rustc }} 97 | # rustup target install wasm32-unknown-unknown 98 | # - uses: actions/checkout@v2 99 | # - name: Functional testing 100 | # run: | 101 | # cd examples/web 102 | # cargo check --features funtest 103 | 104 | quality: 105 | strategy: 106 | matrix: 107 | rustc: ["nightly"] 108 | runs-on: ubuntu-latest 109 | steps: 110 | - uses: actions/checkout@v2 111 | - name: Install dependencies 112 | run: | 113 | rustup default ${{ matrix.rustc }} 114 | rustup component add rustfmt 115 | - name: rustfmt 116 | run: | 117 | cargo fmt -- --check 118 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | Cargo.lock 3 | **/dist 4 | **/node_modules 5 | **/package-lock.json 6 | **/pkg 7 | **/yarn.lock 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | 3 | rust: 4 | - stable 5 | - beta 6 | - nightly 7 | 8 | os: 9 | - linux 10 | - osx 11 | 12 | install: 13 | - if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get update -qq && sudo apt-get install -y libxrandr-dev xorg-dev; fi 14 | - cargo install --force cargo-sync-readme 15 | 16 | script: 17 | - rustc --version 18 | - cargo --version 19 | - cargo build 20 | - cargo test 21 | - cd $TRAVIS_BUILD_DIR/luminance 22 | - if [ "$TRAVIS_OS_NAME" == "windows" ]; then cargo sync-readme -c -f bin --crlf; else cargo sync-readme -c -f bin; fi 23 | - cd $TRAVIS_BUILD_DIR/luminance-derive 24 | - if [ "$TRAVIS_OS_NAME" == "windows" ]; then cargo sync-readme -c -f bin --crlf; else cargo sync-readme -c -f bin; fi 25 | - cd $TRAVIS_BUILD_DIR/luminance-glfw 26 | - if [ "$TRAVIS_OS_NAME" == "windows" ]; then cargo sync-readme -c -f bin --crlf; else cargo sync-readme -c -f bin; fi 27 | - cd $TRAVIS_BUILD_DIR/luminance-glutin 28 | - if [ "$TRAVIS_OS_NAME" == "windows" ]; then cargo sync-readme -c -f bin --crlf; else cargo sync-readme -c -f bin; fi 29 | - cd $TRAVIS_BUILD_DIR/luminance-windowing 30 | - if [ "$TRAVIS_OS_NAME" == "windows" ]; then cargo sync-readme -c -f bin --crlf; else cargo sync-readme -c -f bin; fi 31 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = [ 4 | "examples/common", 5 | "examples/desktop", 6 | # "examples/web", 7 | "luminance", 8 | "luminance-derive", 9 | # "luminance-front", 10 | "luminance-gl2", 11 | "luminance-glfw", 12 | # "luminance-glutin", 13 | # "luminance-sdl2", 14 | # "luminance-std140", 15 | # "luminance-webgl", 16 | # "luminance-web-sys", 17 | ] 18 | 19 | default-members = [ 20 | "examples/common", 21 | "examples/desktop", 22 | "luminance", 23 | "luminance-derive", 24 | # "luminance-front", 25 | "luminance-gl2", 26 | "luminance-glfw", 27 | # "luminance-glutin", 28 | #"luminance-sdl2", # commented out because of 29 | # "luminance-std140", 30 | ] 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /NEXT.md: -------------------------------------------------------------------------------- 1 | # Next changes to be available 2 | 3 | > This document lists all the last changes that occurred lately and that are about to be publicly available soon. These 4 | > are items that must be formatted accordingly and ready to be moved to the [CHANGELOG](./CHANGELOG.md). 5 | 6 | # `luminance` 7 | 8 | # `luminance-derive` 9 | 10 | # `luminance-front` 11 | 12 | # `luminance-gl` 13 | 14 | # `luminance-glfw` 15 | 16 | # `luminance-glutin` 17 | 18 | # `luminance-sdl2` 19 | 20 | # `luminance-std140` 21 | 22 | # `luminance-web-sys` 23 | 24 | # `luminance-webgl` 25 | -------------------------------------------------------------------------------- /docs/imgs/01-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/01-screenshot.png -------------------------------------------------------------------------------- /docs/imgs/02-screenshot-alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/02-screenshot-alt.png -------------------------------------------------------------------------------- /docs/imgs/02-screenshot-alt2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/02-screenshot-alt2.png -------------------------------------------------------------------------------- /docs/imgs/02-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/02-screenshot.png -------------------------------------------------------------------------------- /docs/imgs/03-screenshot-alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/03-screenshot-alt.png -------------------------------------------------------------------------------- /docs/imgs/03-screenshot-alt2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/03-screenshot-alt2.png -------------------------------------------------------------------------------- /docs/imgs/03-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/03-screenshot.png -------------------------------------------------------------------------------- /docs/imgs/04-screenshot-alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/04-screenshot-alt.png -------------------------------------------------------------------------------- /docs/imgs/04-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/04-screenshot.png -------------------------------------------------------------------------------- /docs/imgs/05-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/05-screenshot.png -------------------------------------------------------------------------------- /docs/imgs/08-screenshot-alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/08-screenshot-alt.png -------------------------------------------------------------------------------- /docs/imgs/08-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/08-screenshot.png -------------------------------------------------------------------------------- /docs/imgs/10-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/10-screenshot.png -------------------------------------------------------------------------------- /docs/imgs/displacement_map.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/docs/imgs/displacement_map.gif -------------------------------------------------------------------------------- /docs/renaming.md: -------------------------------------------------------------------------------- 1 | # Renaming 2 | 3 | This document is a short document describing the current features and whether we should rename them. 4 | 5 | 6 | 7 | * [Context](#context) 8 | * [Renaming](#renaming) 9 | * [List of features / vocabulary](#list-of-features--vocabulary) 10 | 11 | 12 | 13 | # Context 14 | 15 | Features in `luminance` has been highly shaped by technology (OpenGL / Vulkan). However, the opinionated API starts to 16 | get augmented with concepts that don’t exist in low-level APIs, such as `ShaderData`, color slots, etc. It might be 17 | necessary to rename the concepts / features to move away from the low-level API and get an API that easier to think 18 | about, and more abstract. 19 | 20 | # Renaming 21 | 22 | ## List of features / vocabulary 23 | 24 | - Framebuffers. 25 | - Color slots. 26 | - Depth slots. 27 | - Shader programs. 28 | - Shader stages. 29 | - Shader data. 30 | - Uniforms. 31 | - Tessellations. 32 | - Vertex. 33 | - Vertex index. 34 | - Instance. 35 | - Textures. 36 | - Samplers. 37 | - Mipmaps. 38 | - Pipelines. 39 | - Shading gates. 40 | - Render gates. 41 | - Tessellation gates. 42 | - Binding points. 43 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Luminance examples 2 | 3 | This directory gathers all the currently available official examples for [luminance]. It is designed to use the 4 | _backend-agnostic_ feature of [luminance]: you write the code once, and executes it on several platform by providing the 5 | platform code to run it. [luminance] code can be imagined as library code that requires an executor to be fully 6 | runnable. 7 | 8 | Currently, two executors exist: 9 | 10 | - [desktop](./desktop): compile the examples as a binary usable from CLI. The examples are selected by passing arguments 11 | to the binary on the command line. 12 | - [web](./web): compile the examples as a WASM module, loaded in a webpack environment, run on a local server. The 13 | examples are selected via the DOM in the browser of your choice. 14 | 15 | Feel free to visit each executor and try them out! 16 | 17 | The actual code for the examples is located in the [common](./common) directory. 18 | 19 | [luminance]: https://crates.io/crates/luminance 20 | -------------------------------------------------------------------------------- /examples/common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-examples" 3 | version = "0.1.0" 4 | authors = ["Dimitri Sabadie "] 5 | description = "Stateless and type-safe graphics framework" 6 | keywords = ["stateless", "type-safe", "graphics", "luminance"] 7 | categories = ["rendering::graphics-api"] 8 | homepage = "https://github.com/phaazon/luminance-rs" 9 | repository = "https://github.com/phaazon/luminance-rs" 10 | documentation = "https://docs.rs/luminance" 11 | readme = "README.md" 12 | edition = "2021" 13 | rust-version = "1.65.0" 14 | 15 | [features] 16 | funtest = [] 17 | funtest-gl33-f64-uniform = [] 18 | 19 | [dependencies] 20 | cgmath = "0.18.0" 21 | env_logger = "0.9.0" 22 | log = "0.4.11" 23 | luminance = { version = "0.48.0-dev", path = "../../luminance", features = ["mint"] } 24 | mint = "0.5.9" 25 | 26 | [dependencies.image] 27 | version = "0.24.1" 28 | default-features = false 29 | features = ["gif", "jpeg", "ico", "png", "pnm", "tga", "tiff", "webp", "bmp", "hdr", "dxt", "dds", "farbfeld"] 30 | -------------------------------------------------------------------------------- /examples/common/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /examples/common/src/adapt-vs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 co; 2 | in vec3 color; 3 | 4 | out vec3 v_color; 5 | 6 | uniform vec2 triangle_pos; 7 | uniform float triangle_size; 8 | 9 | void main() { 10 | gl_Position = vec4(co * triangle_size + triangle_pos, 0., 1.); 11 | v_color = color; 12 | } 13 | -------------------------------------------------------------------------------- /examples/common/src/attributeless-vs.glsl: -------------------------------------------------------------------------------- 1 | out vec3 v_color; 2 | 3 | const vec2[3] TRIANGLE_POS = vec2[]( 4 | vec2(-.5, -.5), 5 | vec2( .5, -.5), 6 | vec2( 0., .5) 7 | ); 8 | 9 | const vec3[3] TRIANGLE_COL = vec3[]( 10 | vec3(1., 0., 0.), 11 | vec3(0., 1., 0.), 12 | vec3(0., 0., 1.) 13 | ); 14 | 15 | void main() { 16 | gl_Position = vec4(TRIANGLE_POS[gl_VertexID], 0., 1.); 17 | v_color = TRIANGLE_COL[gl_VertexID]; 18 | } 19 | -------------------------------------------------------------------------------- /examples/common/src/attributeless.rs: -------------------------------------------------------------------------------- 1 | //! This program demonstrates how to render a triangle without sending anything to the GPU. This is 2 | //! a not-so-famous technique to reduce the bandwidth and procedurally generate all the required 3 | //! data to perform the render. The trick lives in ordering the GPU to render a certain number of 4 | //! vertices and “spawn” the vertices’ data directly in the vertex shader by using the identifier of 5 | //! the vertex currently being mapped over. 6 | //! 7 | //! Press to quit or close the window. 8 | //! 9 | //! 10 | 11 | use luminance::{ 12 | backend::Backend, 13 | context::Context, 14 | dim::{Dim2, Size2}, 15 | framebuffer::{Back, Framebuffer}, 16 | pipeline::PipelineState, 17 | primitive::Triangle, 18 | render_state::RenderState, 19 | shader::{Program, ProgramBuilder}, 20 | vertex_entity::{VertexEntity, VertexEntityBuilder, View}, 21 | }; 22 | 23 | use crate::{shared::FragSlot, Example, InputAction, LoopFeedback, PlatformServices}; 24 | 25 | const VS: &'static str = include_str!("attributeless-vs.glsl"); 26 | const FS: &'static str = include_str!("simple-fs.glsl"); 27 | 28 | pub struct LocalExample { 29 | program: Program<(), (), Triangle, FragSlot, ()>, 30 | attributeless: VertexEntity<(), Triangle, ()>, 31 | back_buffer: Framebuffer, Back<()>>, 32 | } 33 | 34 | impl Example for LocalExample { 35 | type Err = luminance::backend::Error; 36 | 37 | const TITLE: &'static str = "Attributeless"; 38 | 39 | fn bootstrap( 40 | [width, height]: [u32; 2], 41 | _platform: &mut impl PlatformServices, 42 | ctx: &mut Context, 43 | ) -> Result { 44 | // we don’t use a Vertex type anymore (i.e. attributeless, so we use the unit () type) 45 | let program = ctx.new_program( 46 | ProgramBuilder::new() 47 | .add_vertex_stage(VS) 48 | .no_primitive_stage() 49 | .add_shading_stage(FS), 50 | )?; 51 | 52 | // yet, we still need to tell luminance to render a certain number of vertices (even if we send no 53 | // attributes / data); in our case, we’ll just render a triangle, which has three vertices 54 | let attributeless = ctx.new_vertex_entity(VertexEntityBuilder::new())?; 55 | 56 | let back_buffer = ctx.back_buffer(Size2::new(width, height))?; 57 | 58 | Ok(Self { 59 | program, 60 | attributeless, 61 | back_buffer, 62 | }) 63 | } 64 | 65 | fn render_frame( 66 | mut self, 67 | _time: f32, 68 | actions: impl Iterator, 69 | ctx: &mut Context, 70 | ) -> Result, Self::Err> { 71 | for action in actions { 72 | match action { 73 | InputAction::Quit => return Ok(LoopFeedback::Exit), 74 | _ => (), 75 | } 76 | } 77 | 78 | let program = &mut self.program; 79 | let attributeles = &self.attributeless; 80 | 81 | ctx.with_framebuffer(&self.back_buffer, &PipelineState::default(), |mut frame| { 82 | frame.with_program(program, |mut frame| { 83 | frame.with_render_state(&RenderState::default(), |mut frame| { 84 | frame.render_vertex_entity(attributeles.view(..3)) 85 | }) 86 | }) 87 | })?; 88 | 89 | Ok(LoopFeedback::Continue(self)) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /examples/common/src/copy-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 v_uv; 2 | 3 | out vec4 frag; 4 | 5 | uniform sampler2D source_texture; 6 | 7 | void main() { 8 | frag = vec4(texture(source_texture, v_uv).rgb, 1.); 9 | 10 | frag = pow(frag, vec4(1./2.2)); 11 | } 12 | -------------------------------------------------------------------------------- /examples/common/src/copy-multi-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 v_uv; 2 | 3 | out vec4 frag; 4 | 5 | uniform sampler2D source_texture_color; 6 | uniform sampler2D source_texture_white; 7 | 8 | void main() { 9 | vec2 shift = vec2(0.25, 0.0); 10 | frag = vec4(texture(source_texture_color, v_uv + shift).rgb, 1.) 11 | + vec4(texture(source_texture_white, v_uv - shift).rrr, 1.); 12 | 13 | frag = pow(frag, vec4(1./2.2)); 14 | } 15 | -------------------------------------------------------------------------------- /examples/common/src/copy-vs.glsl: -------------------------------------------------------------------------------- 1 | out vec2 v_uv; 2 | 3 | vec2[4] CO = vec2[]( 4 | vec2(-1., -1.), 5 | vec2( 1., -1.), 6 | vec2( 1., 1.), 7 | vec2(-1., 1.) 8 | ); 9 | 10 | void main() { 11 | vec2 p = CO[gl_VertexID]; 12 | 13 | gl_Position = vec4(p, 0., 1.); 14 | v_uv = p * .5 + .5; 15 | } 16 | -------------------------------------------------------------------------------- /examples/common/src/cubemap-viewer-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec3 view_dir; 2 | 3 | out vec3 frag; 4 | 5 | uniform samplerCube skybox; 6 | 7 | void main() { 8 | vec3 cube_color = texture(skybox, view_dir).rgb; 9 | frag = cube_color; 10 | } 11 | -------------------------------------------------------------------------------- /examples/common/src/cubemap-viewer-vs.glsl: -------------------------------------------------------------------------------- 1 | uniform mat4 view; 2 | uniform float fovy; 3 | uniform float aspect_ratio; 4 | 5 | out vec3 view_dir; 6 | 7 | vec2[4] POSITIONS = vec2[]( 8 | vec2(-1., -1.), 9 | vec2( 1., -1.), 10 | vec2(-1., 1.), 11 | vec2( 1., 1.) 12 | ); 13 | 14 | void main() { 15 | gl_Position = vec4(POSITIONS[gl_VertexID], 0., 1.); 16 | 17 | float fovy_2 = fovy * .5; 18 | 19 | vec3 dir = vec3(gl_Position.x, gl_Position.y, -1. / tan(fovy_2)); 20 | 21 | view_dir = -(view * vec4(dir, 1.)).xyz; 22 | 23 | // correct aspect ratio 24 | gl_Position.y *= aspect_ratio; 25 | } 26 | -------------------------------------------------------------------------------- /examples/common/src/displacement-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec3 v_color; 2 | 3 | out vec4 frag; 4 | 5 | uniform float t; 6 | 7 | void main() { 8 | frag = vec4(v_color * vec3(pow(cos(t), 2.), pow(sin(t), 2.), cos(t * .5)), 1.); 9 | frag = pow(frag, vec4(1./2.2)); 10 | } 11 | -------------------------------------------------------------------------------- /examples/common/src/displacement-map-resources/displacement-map-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 v_uv; 2 | out vec4 fragment; 3 | 4 | uniform sampler2D image; 5 | uniform sampler2D displacement_map_1; 6 | uniform sampler2D displacement_map_2; 7 | uniform vec2 window_dimensions; 8 | uniform float displacement_scale; 9 | uniform float time; 10 | 11 | void main() { 12 | vec4 displacement_1 = texture( 13 | displacement_map_1, 14 | mod(window_dimensions * v_uv, 128.0) / 128.0 15 | ) - 0.5; 16 | float scale_1 = sin(time * 3.141592) * displacement_scale; 17 | vec4 displacement_2 = texture( 18 | displacement_map_2, 19 | mod(window_dimensions * v_uv, 101.0) / 101.0 20 | ) - 0.5; 21 | displacement_2.y *= -1.0; 22 | float scale_2 = cos(time * 4.0 * 3.141592) * displacement_scale / 2.0; 23 | vec2 new_uv = mod(v_uv + scale_1 * displacement_1.r + scale_2 * displacement_2.r, 1.0); 24 | 25 | fragment = texture(image, new_uv); 26 | } 27 | -------------------------------------------------------------------------------- /examples/common/src/displacement-map-resources/displacement-map-vs.glsl: -------------------------------------------------------------------------------- 1 | out vec2 v_uv; 2 | 3 | const vec2[4] QUAD_POSITION = vec2[]( 4 | vec2(-1.0, -1.0), 5 | vec2(1.0, -1.0), 6 | vec2(1.0, 1.0), 7 | vec2(-1.0, 1.0) 8 | ); 9 | 10 | void main() { 11 | vec2 position = QUAD_POSITION[gl_VertexID]; 12 | gl_Position = vec4(position, 0.0, 1.0); 13 | v_uv = position * 0.5 + 0.5; 14 | } 15 | -------------------------------------------------------------------------------- /examples/common/src/displacement-map-resources/displacement_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/examples/common/src/displacement-map-resources/displacement_1.png -------------------------------------------------------------------------------- /examples/common/src/displacement-map-resources/displacement_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hadronized/luminance-rs/f01df4b5e57384e88cbef699c8778cb56bd66cef/examples/common/src/displacement-map-resources/displacement_2.png -------------------------------------------------------------------------------- /examples/common/src/displacement-vs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 co; 2 | in vec3 color; 3 | 4 | out vec3 v_color; 5 | 6 | uniform vec2 triangle_pos; 7 | 8 | void main() { 9 | gl_Position = vec4(co + triangle_pos, 0., 1.); 10 | v_color = color; 11 | } 12 | -------------------------------------------------------------------------------- /examples/common/src/dynamic_uniform_interface.rs: -------------------------------------------------------------------------------- 1 | //! This example shows you how to lookup dynamically uniforms into shaders to implement various kind 2 | //! of situations. This feature is very likely to be interesting for anyone who would like to 3 | //! implement a GUI, where the interface of the shader programs are not known statically, for 4 | //! instance. 5 | //! 6 | //! This example looks up the time and the triangle position on the fly, without using the uniform 7 | //! interface. 8 | //! 9 | //! Press the , , , actions to move the triangle on the screen. 10 | //! 11 | //! 12 | 13 | use crate::{ 14 | shared::{FragSlot, Vertex}, 15 | Example, InputAction, LoopFeedback, PlatformServices, 16 | }; 17 | use luminance::{ 18 | backend::Backend, 19 | context::Context, 20 | dim::{Dim2, Size2}, 21 | framebuffer::{Back, Framebuffer}, 22 | pipeline::PipelineState, 23 | primitive::Triangle, 24 | render_state::RenderState, 25 | shader::{Program, ProgramBuilder}, 26 | vertex_entity::{VertexEntity, VertexEntityBuilder, View}, 27 | vertex_storage::{Interleaved, Interleaving}, 28 | }; 29 | 30 | const VS: &'static str = include_str!("displacement-vs.glsl"); 31 | const FS: &'static str = include_str!("displacement-fs.glsl"); 32 | 33 | // Only one triangle this time. 34 | const TRI_VERTICES: [Vertex; 3] = [ 35 | // triangle – an RGB one 36 | // 37 | Vertex::new( 38 | mint::Vector2 { x: 0.5, y: -0.5 }, 39 | mint::Vector3 { 40 | x: 0., 41 | y: 1., 42 | z: 0., 43 | }, 44 | ), 45 | Vertex::new( 46 | mint::Vector2 { x: 0., y: 0.5 }, 47 | mint::Vector3 { 48 | x: 0., 49 | y: 0., 50 | z: 1., 51 | }, 52 | ), 53 | Vertex::new( 54 | mint::Vector2 { x: -0.5, y: -0.5 }, 55 | mint::Vector3 { 56 | x: 1., 57 | y: 0., 58 | z: 0., 59 | }, 60 | ), 61 | ]; 62 | 63 | pub struct LocalExample { 64 | program: Program, // no uniform environment; we want dynamic lookups 65 | triangle: VertexEntity, 66 | triangle_pos: mint::Vector2, 67 | back_buffer: Framebuffer, Back<()>>, 68 | } 69 | 70 | impl Example for LocalExample { 71 | type Err = luminance::backend::Error; 72 | 73 | const TITLE: &'static str = "Dynamic uniform lookup"; 74 | 75 | fn bootstrap( 76 | [width, height]: [u32; 2], 77 | _: &mut impl PlatformServices, 78 | ctx: &mut Context, 79 | ) -> Result { 80 | // notice that we don’t set a uniform interface here: we’re going to look it up on the fly 81 | let program = ctx.new_program( 82 | ProgramBuilder::new() 83 | .add_vertex_stage(VS) 84 | .no_primitive_stage() 85 | .add_shading_stage(FS), 86 | )?; 87 | 88 | let triangle = ctx.new_vertex_entity( 89 | VertexEntityBuilder::new().add_vertices(Interleaved::new().set_vertices(TRI_VERTICES)), 90 | )?; 91 | let triangle_pos = mint::Vector2 { x: 0., y: 0. }; 92 | let back_buffer = ctx.back_buffer(Size2::new(width, height))?; 93 | 94 | Ok(Self { 95 | program, 96 | triangle, 97 | triangle_pos, 98 | back_buffer, 99 | }) 100 | } 101 | 102 | fn render_frame( 103 | mut self, 104 | t: f32, 105 | actions: impl Iterator, 106 | ctx: &mut Context, 107 | ) -> Result, Self::Err> { 108 | for action in actions { 109 | match action { 110 | InputAction::Quit => return Ok(LoopFeedback::Exit), 111 | 112 | InputAction::Left => { 113 | self.triangle_pos.x -= 0.1; 114 | } 115 | 116 | InputAction::Right => { 117 | self.triangle_pos.x += 0.1; 118 | } 119 | 120 | InputAction::Forward => { 121 | self.triangle_pos.y += 0.1; 122 | } 123 | 124 | InputAction::Backward => { 125 | self.triangle_pos.y -= 0.1; 126 | } 127 | 128 | _ => (), 129 | } 130 | } 131 | 132 | let program = &self.program; 133 | let triangle = &self.triangle; 134 | let triangle_pos = &self.triangle_pos; 135 | 136 | ctx.with_framebuffer(&self.back_buffer, &PipelineState::default(), |mut frame| { 137 | frame.with_program(program, |mut frame| { 138 | frame.update(|mut update, _| { 139 | update.query_set::("t", &t)?; 140 | update.query_set::>("triangle_pos", triangle_pos) 141 | })?; 142 | 143 | frame.with_render_state(&RenderState::default(), |mut frame| { 144 | frame.render_vertex_entity(triangle.view(..)) 145 | }) 146 | }) 147 | })?; 148 | 149 | Ok(LoopFeedback::Continue(self)) 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /examples/common/src/env-mapping-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec3 v_nor; 2 | in vec3 v_cam_dir; 3 | in vec3 v_color; 4 | uniform mat4 view; 5 | 6 | out vec3 frag; 7 | 8 | uniform samplerCube environment; 9 | 10 | void main() { 11 | vec3 bounce = reflect(v_cam_dir, normalize(v_nor)); // view space 12 | bounce = inverse(mat3(view)) * bounce; 13 | vec3 color = texture(environment, bounce).rgb; 14 | 15 | frag = color; 16 | } 17 | -------------------------------------------------------------------------------- /examples/common/src/env-mapping-vs.glsl: -------------------------------------------------------------------------------- 1 | in vec3 co3; 2 | in vec3 nor; 3 | 4 | out vec3 v_nor; 5 | out vec3 v_cam_dir; 6 | out vec3 v_color; 7 | 8 | uniform mat4 projection; 9 | uniform mat4 view; 10 | uniform mat4 model; 11 | uniform float aspect_ratio; 12 | 13 | vec3[24] VERTEX_COLORS = vec3[]( 14 | vec3(1., 0., 0.), vec3(1., 0., 0.), vec3(1., 0., 0.), vec3(1., 0., 0.), 15 | vec3(0., 1., 0.), vec3(0., 1., 0.), vec3(0., 1., 0.), vec3(0., 1., 0.), 16 | vec3(0., 0., 1.), vec3(0., 0., 1.), vec3(0., 0., 1.), vec3(0., 0., 1.), 17 | vec3(1., 0., 1.), vec3(1., 0., 1.), vec3(1., 0., 1.), vec3(1., 0., 1.), 18 | vec3(0., 1., 1.), vec3(0., 1., 1.), vec3(0., 1., 1.), vec3(0., 1., 1.), 19 | vec3(1., 1., 0.), vec3(1., 1., 0.), vec3(1., 1., 0.), vec3(1., 1., 0.) 20 | ); 21 | 22 | void main() { 23 | vec4 p = view * vec4(co3, 1.); 24 | gl_Position = projection * p; 25 | 26 | v_nor = mat3(view) * nor; 27 | v_cam_dir = -p.xyz; 28 | v_color = VERTEX_COLORS[gl_VertexID]; 29 | } 30 | -------------------------------------------------------------------------------- /examples/common/src/funtest_360_manually_drop_framebuffer.rs: -------------------------------------------------------------------------------- 1 | //! 2 | //! 3 | //! When a framebuffer is created, dropped and a new one is created, the new framebuffer doesn’t 4 | //! seem to behave correctly. At the time of #360, it was detected on Windows. 5 | //! 6 | //! Because this example simply creates a framebuffer, drops it and creates another one, nothing is 7 | //! displayed and the window flashes on the screen. Run the application in a tool such as apitrace 8 | //! or renderdoc to analyze it. 9 | 10 | use crate::{Example, InputAction, LoopFeedback, PlatformServices}; 11 | use luminance_front::{ 12 | context::GraphicsContext, 13 | framebuffer::Framebuffer, 14 | pixel::{Depth32F, RGBA32F}, 15 | texture::{Dim2, Sampler}, 16 | Backend, 17 | }; 18 | 19 | pub struct LocalExample; 20 | 21 | impl Example for LocalExample { 22 | fn bootstrap( 23 | _: &mut impl PlatformServices, 24 | context: &mut impl GraphicsContext, 25 | ) -> Self { 26 | let framebuffer = 27 | context.new_framebuffer::([1024, 1024], 0, Sampler::default()); 28 | 29 | std::mem::drop(framebuffer); 30 | 31 | // #360 occurs here after the drop 32 | let _ = context.new_framebuffer::([1024, 1024], 0, Sampler::default()); 33 | 34 | LocalExample 35 | } 36 | 37 | fn render_frame( 38 | self, 39 | _: f32, 40 | _: Framebuffer, 41 | _: impl Iterator, 42 | _: &mut impl GraphicsContext, 43 | ) -> LoopFeedback { 44 | LoopFeedback::Exit 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/common/src/funtest_483_indices_mut_corruption.rs: -------------------------------------------------------------------------------- 1 | use crate::{shared::Vertex, Example, InputAction, LoopFeedback, PlatformServices}; 2 | use luminance_front::{context::GraphicsContext, framebuffer::Framebuffer, texture::Dim2, Backend}; 3 | use std::ops::Deref as _; 4 | 5 | pub struct LocalExample; 6 | 7 | impl Example for LocalExample { 8 | fn bootstrap( 9 | _: &mut impl PlatformServices, 10 | context: &mut impl GraphicsContext, 11 | ) -> Self { 12 | let vertices = [ 13 | Vertex::new([1., 2.].into(), [1., 1., 1.].into()), 14 | Vertex::new([-1., 2.].into(), [1., 0., 1.].into()), 15 | Vertex::new([1., -2.].into(), [1., 1., 0.].into()), 16 | ]; 17 | let mut tess = context 18 | .new_tess() 19 | .set_vertices(&vertices[..]) 20 | .set_indices([0u8, 1, 2]) 21 | .set_mode(luminance_front::tess::Mode::Point) 22 | .build() 23 | .expect("tessellation"); 24 | 25 | tess 26 | .indices_mut() 27 | .expect("sliced indices") 28 | .copy_from_slice(&[10, 20, 30]); 29 | 30 | { 31 | let slice = tess.indices().expect("sliced indices"); 32 | log::info!("slice after mutation is: {:?}", slice.deref()); 33 | } 34 | 35 | { 36 | let _ = tess.indices_mut().expect("sliced indices"); 37 | } 38 | 39 | drop(tess); 40 | 41 | LocalExample 42 | } 43 | 44 | fn render_frame( 45 | self, 46 | _: f32, 47 | _: Framebuffer, 48 | _: impl Iterator, 49 | _: &mut impl GraphicsContext, 50 | ) -> LoopFeedback { 51 | LoopFeedback::Exit 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /examples/common/src/funtest_flatten_slice.rs: -------------------------------------------------------------------------------- 1 | use crate::{Example, InputAction, LoopFeedback, PlatformServices}; 2 | use cgmath::{Matrix4, Vector3}; 3 | use luminance::{Semantics, Vertex}; 4 | use luminance_front::{ 5 | context::GraphicsContext, 6 | framebuffer::Framebuffer, 7 | pipeline::PipelineState, 8 | render_state::RenderState, 9 | shader::{types::Mat44, BuiltProgram, Program}, 10 | tess::{Interleaved, Mode, Tess}, 11 | texture::Dim2, 12 | Backend, 13 | }; 14 | 15 | const VS: &str = " 16 | in vec2 co; 17 | 18 | uniform mat4 translation_mat; 19 | uniform float aspect_ratio; 20 | 21 | void main() { 22 | vec2 p = co; 23 | p.y *= aspect_ratio; 24 | gl_Position = translation_mat * vec4(p, 0., 1.); 25 | } 26 | "; 27 | 28 | const FS: &str = " 29 | out vec4 frag; 30 | 31 | void main() { 32 | frag = vec4(1., .5, .5, 1.); 33 | } 34 | "; 35 | 36 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Semantics)] 37 | pub enum Semantics { 38 | // - Reference vertex positions with the "co" variable in vertex shaders. 39 | // - The underlying representation is [f32; 2], which is a vec2 in GLSL. 40 | // - The wrapper type you can use to handle such a semantics is VertexPosition. 41 | #[sem(name = "co", repr = "[f32; 2]", wrapper = "VertexPosition")] 42 | Position, 43 | } 44 | 45 | #[repr(C)] 46 | #[derive(Clone, Copy, Debug, PartialEq, Vertex)] 47 | #[vertex(sem = "Semantics")] 48 | struct Vertex { 49 | pos: VertexPosition, 50 | } 51 | 52 | // The vertices. 53 | const TRI_VERTICES: [Vertex; 3] = [ 54 | Vertex::new(VertexPosition::new([0.5, -0.5])), 55 | Vertex::new(VertexPosition::new([0.0, 0.5])), 56 | Vertex::new(VertexPosition::new([-0.5, -0.5])), 57 | ]; 58 | 59 | pub struct LocalExample { 60 | program: Program, 61 | triangle: Tess, 62 | } 63 | 64 | impl Example for LocalExample { 65 | fn bootstrap( 66 | _: &mut impl PlatformServices, 67 | context: &mut impl GraphicsContext, 68 | ) -> Self { 69 | let BuiltProgram { program, warnings } = context 70 | .new_shader_program::() 71 | .from_strings(VS, None, None, FS) 72 | .expect("program creation"); 73 | 74 | for warning in warnings { 75 | log::info!("{}", warning); 76 | } 77 | 78 | let triangle = context 79 | .new_tess() 80 | .set_vertices(&TRI_VERTICES[..]) 81 | .set_mode(Mode::Triangle) 82 | .build() 83 | .unwrap(); 84 | 85 | LocalExample { program, triangle } 86 | } 87 | 88 | fn render_frame( 89 | mut self, 90 | _: f32, 91 | back_buffer: Framebuffer, 92 | actions: impl Iterator, 93 | context: &mut impl GraphicsContext, 94 | ) -> LoopFeedback { 95 | for action in actions { 96 | match action { 97 | InputAction::Quit => return LoopFeedback::Exit, 98 | _ => (), 99 | } 100 | } 101 | 102 | let translation_mat = Matrix4::from_translation(Vector3::new(0.5, 0., 0.)); 103 | let program = &mut self.program; 104 | let triangle = &self.triangle; 105 | 106 | let render = context 107 | .new_pipeline_gate() 108 | .pipeline( 109 | &back_buffer, 110 | &PipelineState::default(), 111 | |_, mut shd_gate| { 112 | shd_gate.shade(program, |mut iface, _, mut rdr_gate| { 113 | let uni = iface 114 | .query() 115 | .unwrap() 116 | .ask::>("translation_mat") 117 | .unwrap(); 118 | let mat = Mat44::new(translation_mat); 119 | iface.set(&uni, mat); 120 | 121 | // aspect ratio 122 | let [width, height] = back_buffer.size(); 123 | let aspect_ratio_uni = iface.query().unwrap().ask::("aspect_ratio").unwrap(); 124 | iface.set(&aspect_ratio_uni, width as f32 / height as f32); 125 | 126 | rdr_gate.render(&RenderState::default(), |mut tess_gate| { 127 | tess_gate.render(triangle) 128 | }) 129 | }) 130 | }, 131 | ) 132 | .assume(); 133 | 134 | if render.is_ok() { 135 | LoopFeedback::Continue(self) 136 | } else { 137 | LoopFeedback::Exit 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /examples/common/src/funtest_gl33_f64_uniform.rs: -------------------------------------------------------------------------------- 1 | use crate::{Example, InputAction, LoopFeedback, PlatformServices}; 2 | use luminance::UniformInterface; 3 | use luminance_front::{ 4 | context::GraphicsContext, 5 | framebuffer::Framebuffer, 6 | pipeline::PipelineState, 7 | render_state::RenderState, 8 | shader::{types::Vec3, Program, Uniform}, 9 | tess::{Mode, Tess}, 10 | texture::Dim2, 11 | Backend, 12 | }; 13 | 14 | const VS: &str = " 15 | const vec2[4] POSITIONS = vec2[]( 16 | vec2(-1., -1.), 17 | vec2( 1., -1.), 18 | vec2( 1., 1.), 19 | vec2(-1., 1.) 20 | ); 21 | 22 | void main() { 23 | gl_Position = vec4(POSITIONS[gl_VertexID], 0., 1.); 24 | }"; 25 | 26 | const FS: &str = " 27 | out vec3 frag; 28 | 29 | uniform dvec3 color; 30 | 31 | void main() { 32 | frag = vec3(color); 33 | }"; 34 | 35 | #[derive(Debug, UniformInterface)] 36 | struct ShaderInterface { 37 | color: Uniform>, 38 | } 39 | 40 | pub struct LocalExample { 41 | program: Program<(), (), ShaderInterface>, 42 | tess: Tess<()>, 43 | } 44 | 45 | impl Example for LocalExample { 46 | fn bootstrap( 47 | _: &mut impl PlatformServices, 48 | context: &mut impl GraphicsContext, 49 | ) -> Self { 50 | let program = context 51 | .new_shader_program::<(), (), ShaderInterface>() 52 | .from_strings(VS, None, None, FS) 53 | .unwrap() 54 | .ignore_warnings(); 55 | 56 | let tess = context 57 | .new_tess() 58 | .set_mode(Mode::TriangleFan) 59 | .set_render_vertex_nb(4) 60 | .build() 61 | .unwrap(); 62 | 63 | LocalExample { program, tess } 64 | } 65 | 66 | fn render_frame( 67 | mut self, 68 | t: f32, 69 | back_buffer: Framebuffer, 70 | actions: impl Iterator, 71 | context: &mut impl GraphicsContext, 72 | ) -> LoopFeedback { 73 | for action in actions { 74 | match action { 75 | InputAction::Quit => return LoopFeedback::Exit, 76 | _ => (), 77 | } 78 | } 79 | 80 | let t = t as f64; 81 | let color = Vec3::new(t.cos(), 0.3, t.sin()); 82 | let program = &mut self.program; 83 | let tess = &self.tess; 84 | 85 | let render = context 86 | .new_pipeline_gate() 87 | .pipeline( 88 | &back_buffer, 89 | &PipelineState::default(), 90 | |_, mut shd_gate| { 91 | shd_gate.shade(program, |mut iface, uni, mut rdr_gate| { 92 | iface.set(&uni.color, color); 93 | 94 | rdr_gate.render(&RenderState::default(), |mut tess_gate| { 95 | tess_gate.render(tess) 96 | }) 97 | }) 98 | }, 99 | ) 100 | .assume(); 101 | 102 | if render.is_ok() { 103 | LoopFeedback::Continue(self) 104 | } else { 105 | LoopFeedback::Exit 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /examples/common/src/funtest_pixel_array_encoding.rs: -------------------------------------------------------------------------------- 1 | use crate::{Example, InputAction, LoopFeedback, PlatformServices}; 2 | use luminance_front::{ 3 | context::GraphicsContext, 4 | framebuffer::Framebuffer, 5 | pixel::RGB8UI, 6 | texture::{Dim2, Sampler, TexelUpload, Texture}, 7 | Backend, 8 | }; 9 | 10 | pub struct LocalExample; 11 | 12 | impl Example for LocalExample { 13 | fn bootstrap( 14 | _: &mut impl PlatformServices, 15 | context: &mut impl GraphicsContext, 16 | ) -> Self { 17 | let _texture: Texture = context 18 | .new_texture([100, 100], Sampler::default(), TexelUpload::reserve(0)) 19 | .unwrap(); 20 | 21 | LocalExample 22 | } 23 | 24 | fn render_frame( 25 | self, 26 | _: f32, 27 | _: Framebuffer, 28 | _: impl Iterator, 29 | _: &mut impl GraphicsContext, 30 | ) -> LoopFeedback { 31 | LoopFeedback::Exit 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/common/src/funtest_scissor_test.rs: -------------------------------------------------------------------------------- 1 | use crate::{Example, InputAction, LoopFeedback, PlatformServices}; 2 | use luminance_front::{ 3 | context::GraphicsContext, 4 | framebuffer::Framebuffer, 5 | pipeline::PipelineState, 6 | render_state::RenderState, 7 | scissor::ScissorRegion, 8 | shader::Program, 9 | tess::{Mode, Tess}, 10 | texture::Dim2, 11 | Backend, 12 | }; 13 | 14 | const VS: &str = " 15 | const vec2[4] POSITIONS = vec2[]( 16 | vec2(-1., -1.), 17 | vec2( 1., -1.), 18 | vec2( 1., 1.), 19 | vec2(-1., 1.) 20 | ); 21 | 22 | void main() { 23 | gl_Position = vec4(POSITIONS[gl_VertexID], 0., 1.); 24 | }"; 25 | 26 | const FS: &str = " 27 | out vec4 frag; 28 | 29 | void main() { 30 | frag = vec4(1., .5, .5, 1.); 31 | }"; 32 | 33 | pub struct LocalExample { 34 | program: Program<(), (), ()>, 35 | tess: Tess<()>, 36 | is_active: bool, 37 | } 38 | 39 | impl Example for LocalExample { 40 | fn bootstrap( 41 | _: &mut impl PlatformServices, 42 | context: &mut impl GraphicsContext, 43 | ) -> Self { 44 | let program = context 45 | .new_shader_program::<(), (), ()>() 46 | .from_strings(VS, None, None, FS) 47 | .unwrap() 48 | .ignore_warnings(); 49 | 50 | let tess = context 51 | .new_tess() 52 | .set_mode(Mode::TriangleFan) 53 | .set_render_vertex_nb(4) 54 | .build() 55 | .unwrap(); 56 | 57 | LocalExample { 58 | program, 59 | tess, 60 | is_active: true, 61 | } 62 | } 63 | 64 | fn render_frame( 65 | mut self, 66 | _: f32, 67 | back_buffer: Framebuffer, 68 | actions: impl Iterator, 69 | context: &mut impl GraphicsContext, 70 | ) -> LoopFeedback { 71 | for action in actions { 72 | match action { 73 | InputAction::PrimaryReleased => { 74 | self.is_active = !self.is_active; 75 | log::info!( 76 | "scissor test is {}", 77 | if self.is_active { "active" } else { "inactive" }, 78 | ); 79 | } 80 | 81 | InputAction::Quit => return LoopFeedback::Exit, 82 | _ => (), 83 | } 84 | } 85 | 86 | let [width, height] = back_buffer.size(); 87 | let (w2, h2) = (width as u32 / 2, height as u32 / 2); 88 | let program = &mut self.program; 89 | let tess = &self.tess; 90 | let is_active = self.is_active; 91 | 92 | let render = context 93 | .new_pipeline_gate() 94 | .pipeline( 95 | &back_buffer, 96 | &PipelineState::default(), 97 | |_, mut shd_gate| { 98 | shd_gate.shade(program, |_, _, mut rdr_gate| { 99 | if is_active { 100 | let rdr_st = RenderState::default().set_scissor(ScissorRegion { 101 | x: w2 - w2 / 2, 102 | y: h2 - h2 / 2, 103 | width: w2, 104 | height: h2, 105 | }); 106 | 107 | rdr_gate.render(&rdr_st, |mut tess_gate| tess_gate.render(tess)) 108 | } else { 109 | rdr_gate.render(&RenderState::default(), |mut tess_gate| { 110 | tess_gate.render(tess) 111 | }) 112 | } 113 | }) 114 | }, 115 | ) 116 | .assume(); 117 | 118 | if render.is_ok() { 119 | LoopFeedback::Continue(self) 120 | } else { 121 | LoopFeedback::Exit 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /examples/common/src/funtest_tess_no_data.rs: -------------------------------------------------------------------------------- 1 | use crate::{Example, InputAction, LoopFeedback, PlatformServices}; 2 | use luminance_front::{ 3 | context::GraphicsContext, framebuffer::Framebuffer, tess::TessError, texture::Dim2, Backend, 4 | }; 5 | 6 | pub struct LocalExample; 7 | 8 | impl Example for LocalExample { 9 | fn bootstrap( 10 | _: &mut impl PlatformServices, 11 | context: &mut impl GraphicsContext, 12 | ) -> Self { 13 | let tess = context.new_tess().build(); 14 | assert!(matches!(tess, Err(TessError::NoData))); 15 | LocalExample 16 | } 17 | 18 | fn render_frame( 19 | self, 20 | _: f32, 21 | _: Framebuffer, 22 | _: impl Iterator, 23 | _: &mut impl GraphicsContext, 24 | ) -> LoopFeedback { 25 | LoopFeedback::Exit 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/common/src/instancing-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec3 v_color; 2 | in float v_instance_bias; 3 | 4 | out vec4 frag; 5 | 6 | uniform float t; 7 | 8 | void main() { 9 | float q = v_instance_bias * 10. + t; 10 | frag = vec4(v_color * vec3(pow(cos(q), 2.), pow(sin(q), 2.), cos(q * .5)), 1.); 11 | frag = pow(frag, vec4(1./2.2)); 12 | } 13 | -------------------------------------------------------------------------------- /examples/common/src/instancing-vs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 co; 2 | in vec3 color; 3 | in vec2 position; 4 | in float weight; 5 | 6 | out vec3 v_color; 7 | out float v_instance_bias; 8 | 9 | void main() { 10 | gl_Position = vec4(co * weight + position, 0., 1.); 11 | v_color = color; 12 | v_instance_bias = float(gl_InstanceID); 13 | } 14 | -------------------------------------------------------------------------------- /examples/common/src/multi-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec3 v_color; 2 | 3 | out vec3 frag_color; 4 | out float frag_white; 5 | 6 | void main() { 7 | frag_color = v_color.rgb; 8 | frag_white = 1.; 9 | } 10 | -------------------------------------------------------------------------------- /examples/common/src/query_info.rs: -------------------------------------------------------------------------------- 1 | //! This program demonstrates the Query API, allowing to get information about the GPU and the backend. This example 2 | //! outputs the information via the `log` crate via `log::info`, so don’t forget to enable information level in the 3 | //! executor you choose. 4 | //! 5 | //! 6 | 7 | use crate::{Example, InputAction, LoopFeedback, PlatformServices}; 8 | use luminance::{backend::Backend, context::Context}; 9 | 10 | pub struct LocalExample; 11 | 12 | impl Example for LocalExample { 13 | type Err = luminance::backend::Error; 14 | 15 | const TITLE: &'static str = "Query Info"; 16 | 17 | fn bootstrap( 18 | _: [u32; 2], 19 | _: &mut impl PlatformServices, 20 | ctx: &mut Context, 21 | ) -> Result { 22 | log::info!("Backend author: {:?}", ctx.backend_author()); 23 | log::info!("Backend name: {:?}", ctx.backend_name()); 24 | log::info!("Backend version: {:?}", ctx.backend_version()); 25 | log::info!( 26 | "Backend shading language version: {:?}", 27 | ctx.backend_shading_lang_version() 28 | ); 29 | 30 | Ok(LocalExample) 31 | } 32 | 33 | fn render_frame( 34 | self, 35 | _: f32, 36 | _: impl Iterator, 37 | _: &mut Context, 38 | ) -> Result, Self::Err> { 39 | Ok(LoopFeedback::Exit) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /examples/common/src/shader_uniforms.rs: -------------------------------------------------------------------------------- 1 | //! This program shows how to render a triangle and change its position and color on the fly by 2 | //! updating “shader uniforms”. Those are values stored on the GPU that remain constant for the 3 | //! whole duration of a draw call (you typically change it between each draw call to customize each 4 | //! draw). 5 | //! 6 | //! This example demonstrate how to add time to your shader to start building moving and animated 7 | //! effects. 8 | //! 9 | //! Press the , , and to move the triangle on 10 | //! the screen. 11 | //! 12 | //! 13 | 14 | use luminance::{ 15 | backend::Backend, 16 | context::Context, 17 | dim::{Dim2, Size2}, 18 | framebuffer::{Back, Framebuffer}, 19 | pipeline::PipelineState, 20 | primitive::Triangle, 21 | render_state::RenderState, 22 | shader::{Program, ProgramBuilder, Uni}, 23 | vertex_entity::{VertexEntity, VertexEntityBuilder, View}, 24 | vertex_storage::{Interleaved, Interleaving}, 25 | Uniforms, 26 | }; 27 | use mint::{Vector2, Vector3}; 28 | 29 | use crate::{ 30 | shared::{FragSlot, Vertex}, 31 | Example, InputAction, LoopFeedback, PlatformServices, 32 | }; 33 | 34 | const VS: &'static str = include_str!("displacement-vs.glsl"); 35 | const FS: &'static str = include_str!("displacement-fs.glsl"); 36 | 37 | // Only one triangle this time. 38 | const TRI_VERTICES: [Vertex; 3] = [ 39 | Vertex::new( 40 | Vector2 { x: 0.5, y: -0.5 }, 41 | Vector3 { 42 | x: 1., 43 | y: 0., 44 | z: 0., 45 | }, 46 | ), 47 | Vertex::new( 48 | Vector2 { x: 0.0, y: 0.5 }, 49 | Vector3 { 50 | x: 0., 51 | y: 1., 52 | z: 0., 53 | }, 54 | ), 55 | Vertex::new( 56 | Vector2 { x: -0.5, y: -0.5 }, 57 | Vector3 { 58 | x: 0., 59 | y: 0., 60 | z: 1., 61 | }, 62 | ), 63 | ]; 64 | 65 | // Create a uniform interface. This is a type that will be used to customize the shader. In our 66 | // case, we just want to pass the time and the position of the triangle, for instance. 67 | // 68 | // This macro only supports structs for now; you cannot use enums as uniform interfaces. 69 | #[derive(Debug, Uniforms)] 70 | struct ShaderUniforms { 71 | #[uniform(name = "t")] 72 | time: Uni, 73 | triangle_pos: Uni<[f32; 2]>, 74 | } 75 | 76 | pub struct LocalExample { 77 | program: Program, 78 | triangle: VertexEntity, 79 | triangle_pos: Vector2, 80 | back_buffer: Framebuffer, Back<()>>, 81 | } 82 | 83 | impl Example for LocalExample { 84 | type Err = luminance::backend::Error; 85 | 86 | const TITLE: &'static str = "Shader Uniforms"; 87 | 88 | fn bootstrap( 89 | [width, height]: [u32; 2], 90 | _platform: &mut impl PlatformServices, 91 | ctx: &mut Context, 92 | ) -> Result { 93 | let program = ctx.new_program( 94 | ProgramBuilder::new() 95 | .add_vertex_stage(VS) 96 | .no_primitive_stage() 97 | .add_shading_stage(FS), 98 | )?; 99 | let triangle = ctx.new_vertex_entity( 100 | VertexEntityBuilder::new().add_vertices(Interleaved::new().set_vertices(&TRI_VERTICES[..])), 101 | )?; 102 | let triangle_pos = Vector2 { x: 0., y: 0. }; 103 | let back_buffer = ctx.back_buffer(Size2::new(width, height))?; 104 | 105 | Ok(Self { 106 | program, 107 | triangle, 108 | triangle_pos, 109 | back_buffer, 110 | }) 111 | } 112 | 113 | fn render_frame( 114 | mut self, 115 | t: f32, 116 | actions: impl Iterator, 117 | ctx: &mut Context, 118 | ) -> Result, Self::Err> { 119 | for action in actions { 120 | match action { 121 | InputAction::Quit => return Ok(LoopFeedback::Exit), 122 | InputAction::Left => self.triangle_pos.x -= 0.1, 123 | InputAction::Right => self.triangle_pos.x += 0.1, 124 | InputAction::Forward => self.triangle_pos.y += 0.1, 125 | InputAction::Backward => self.triangle_pos.y -= 0.1, 126 | _ => (), 127 | } 128 | } 129 | 130 | let program = &self.program; 131 | let triangle = &self.triangle; 132 | let triangle_pos = self.triangle_pos; 133 | 134 | ctx.with_framebuffer(&self.back_buffer, &PipelineState::default(), |mut frame| { 135 | frame.with_program(program, |mut frame| { 136 | frame.update(|mut program, unis| { 137 | program.set(&unis.time, &t)?; 138 | program.set(&unis.triangle_pos, triangle_pos.as_ref()) 139 | })?; 140 | 141 | frame.with_render_state(&RenderState::default(), |mut frame| { 142 | frame.render_vertex_entity(triangle.view(..)) 143 | }) 144 | }) 145 | })?; 146 | 147 | Ok(LoopFeedback::Continue(self)) 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /examples/common/src/shared.rs: -------------------------------------------------------------------------------- 1 | use crate::PlatformServices; 2 | use luminance::{dim::Size2, namespace, pixel::NormRGB8UI, RenderSlots, Vertex}; 3 | use mint::{Vector2, Vector3}; 4 | 5 | // Render slots. 6 | // 7 | // A render slot represents the channels the end stage of a shader program is going to end up writing to. In our case, 8 | // since we are only interested in rendering the color of each pixel, we will just have one single channel for the 9 | // color. 10 | #[derive(Clone, Copy, Debug, PartialEq, RenderSlots)] 11 | pub struct FragSlot { 12 | frag: NormRGB8UI, 13 | } 14 | 15 | namespace! { 16 | Namespace = { 17 | "co", 18 | "co3", 19 | "color", 20 | "nor", 21 | "position", 22 | "weight" 23 | } 24 | } 25 | 26 | #[repr(C)] 27 | #[derive(Clone, Copy, Debug, PartialEq, Vertex)] 28 | #[vertex(namespace = "Namespace")] 29 | pub struct Vertex { 30 | pub co: Vector2, 31 | pub color: Vector3, 32 | } 33 | 34 | impl Vertex { 35 | pub const fn new(co: Vector2, color: Vector3) -> Self { 36 | Self { co, color } 37 | } 38 | } 39 | 40 | // definition of a single instance 41 | #[repr(C)] 42 | #[derive(Clone, Copy, Debug, PartialEq, Vertex)] 43 | #[vertex(namespace = "Namespace")] 44 | pub struct Instance { 45 | pub position: Vector2, 46 | pub weight: f32, 47 | } 48 | 49 | impl Instance { 50 | pub const fn new(position: Vector2, weight: f32) -> Self { 51 | Self { position, weight } 52 | } 53 | } 54 | 55 | #[repr(C)] 56 | #[derive(Clone, Copy, Debug, PartialEq, Vertex)] 57 | #[vertex(namespace = "Namespace")] 58 | pub struct CubeVertex { 59 | pub co3: Vector3, 60 | pub nor: Vector3, 61 | } 62 | 63 | impl CubeVertex { 64 | pub const fn new(co3: Vector3, nor: Vector3) -> Self { 65 | Self { co3, nor } 66 | } 67 | } 68 | 69 | // Simple interleaved cube of given size. 70 | #[rustfmt::skip] 71 | pub fn cube(size: f32) -> ([CubeVertex; 24], [u32; 30]) { 72 | let s = size * 0.5; 73 | 74 | let vertices = [ 75 | // first face 76 | CubeVertex::new([-s, -s, s].into(), [ 0., 0., 1.].into()), 77 | CubeVertex::new([ s, -s, s].into(), [ 0., 0., 1.].into()), 78 | CubeVertex::new([-s, s, s].into(), [ 0., 0., 1.].into()), 79 | CubeVertex::new([ s, s, s].into(), [ 0., 0., 1.].into()), 80 | // second face 81 | CubeVertex::new([ s, -s, -s].into(), [ 0., 0., -1.].into()), 82 | CubeVertex::new([-s, -s, -s].into(), [ 0., 0., -1.].into()), 83 | CubeVertex::new([ s, s, -s].into(), [ 0., 0., -1.].into()), 84 | CubeVertex::new([-s, s, -s].into(), [ 0., 0., -1.].into()), 85 | // third face 86 | CubeVertex::new([ s, -s, s].into(), [ 1., 0., 0.].into()), 87 | CubeVertex::new([ s, -s, -s].into(), [ 1., 0., 0.].into()), 88 | CubeVertex::new([ s, s, s].into(), [ 1., 0., 0.].into()), 89 | CubeVertex::new([ s, s, -s].into(), [ 1., 0., 0.].into()), 90 | // forth face 91 | CubeVertex::new([-s, -s, -s].into(), [-1., 0., 0.].into()), 92 | CubeVertex::new([-s, -s, s].into(), [-1., 0., 0.].into()), 93 | CubeVertex::new([-s, s, -s].into(), [-1., 0., 0.].into()), 94 | CubeVertex::new([-s, s, s].into(), [-1., 0., 0.].into()), 95 | // fifth face 96 | CubeVertex::new([-s, s, s].into(), [ 0., 1., 0.].into()), 97 | CubeVertex::new([ s, s, s].into(), [ 0., 1., 0.].into()), 98 | CubeVertex::new([-s, s, -s].into(), [ 0., 1., 0.].into()), 99 | CubeVertex::new([ s, s, -s].into(), [ 0., 1., 0.].into()), 100 | // sixth face 101 | CubeVertex::new([-s, -s, -s].into(), [ 0., -1., 0.].into()), 102 | CubeVertex::new([ s, -s, -s].into(), [ 0., -1., 0.].into()), 103 | CubeVertex::new([-s, -s, s].into(), [ 0., -1., 0.].into()), 104 | CubeVertex::new([ s, -s, s].into(), [ 0., -1., 0.].into()), 105 | ]; 106 | 107 | let indices = [ 108 | 0, 1, 2, 3, u32::max_value(), 109 | 4, 5, 6, 7, u32::max_value(), 110 | 8, 9, 10, 11, u32::max_value(), 111 | 12, 13, 14, 15, u32::max_value(), 112 | 16, 17, 18, 19, u32::max_value(), 113 | 20, 21, 22, 23, u32::max_value(), 114 | ]; 115 | 116 | (vertices, indices) 117 | } 118 | 119 | pub fn load_img(platform: &mut impl PlatformServices) -> Option<(Size2, Vec)> { 120 | let img = platform 121 | .fetch_texture() 122 | .map_err(|e| log::error!("error while loading image: {}", e)) 123 | .ok()?; 124 | let (width, height) = img.dimensions(); 125 | let texels = img.into_raw(); 126 | log::info!("loaded texture with width={} height={}", width, height); 127 | 128 | Some((Size2::new(width, height), texels)) 129 | } 130 | -------------------------------------------------------------------------------- /examples/common/src/simple-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec3 v_color; 2 | 3 | out vec4 frag; 4 | 5 | void main() { 6 | frag = vec4(v_color, 1.); 7 | } 8 | -------------------------------------------------------------------------------- /examples/common/src/simple-vs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 co; 2 | in vec3 color; 3 | 4 | out vec3 v_color; 5 | 6 | void main() { 7 | gl_Position = vec4(co, 0., 1.); 8 | v_color = color; 9 | } 10 | -------------------------------------------------------------------------------- /examples/common/src/texture-fs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 v_uv; 2 | out vec4 frag; 3 | 4 | uniform sampler2D tex; 5 | 6 | void main() { 7 | frag = texture(tex, v_uv); 8 | } 9 | -------------------------------------------------------------------------------- /examples/common/src/texture-vs.glsl: -------------------------------------------------------------------------------- 1 | out vec2 v_uv; 2 | 3 | const vec2[4] QUAD_POS = vec2[]( 4 | vec2(-1., -1.), 5 | vec2( 1., -1.), 6 | vec2( 1., 1.), 7 | vec2(-1., 1.) 8 | ); 9 | 10 | void main() { 11 | vec2 p = QUAD_POS[gl_VertexID]; 12 | 13 | gl_Position = vec4(p, 0., 1.); 14 | v_uv = p * .5 + .5; // transform the position of the vertex into UV space 15 | } 16 | -------------------------------------------------------------------------------- /examples/common/src/texture.rs: -------------------------------------------------------------------------------- 1 | //! This program is a showcase to demonstrate how you can use a texture from an image loaded from the disk. 2 | //! For the purpose of simplicity, the image is stretched to match your window resolution. 3 | //! 4 | //! > Note: for this example, it is recommended to compile with --release to speed up image loading. 5 | //! 6 | //! 7 | 8 | use crate::{ 9 | shared::{load_img, FragSlot}, 10 | Example, InputAction, LoopFeedback, PlatformServices, 11 | }; 12 | use luminance::{ 13 | backend::{Backend, Error}, 14 | blending::{Blending, BlendingMode, Equation, Factor}, 15 | context::Context, 16 | dim::{Dim2, Size2}, 17 | framebuffer::{Back, Framebuffer}, 18 | pipeline::PipelineState, 19 | pixel::{NormRGB8UI, NormUnsigned}, 20 | primitive::TriangleFan, 21 | render_state::RenderState, 22 | shader::{Program, ProgramBuilder, Uni}, 23 | texture::{InUseTexture, Mipmaps, Texture, TextureSampling}, 24 | vertex_entity::{VertexEntity, VertexEntityBuilder, View}, 25 | Uniforms, 26 | }; 27 | 28 | const VS: &'static str = include_str!("texture-vs.glsl"); 29 | const FS: &'static str = include_str!("texture-fs.glsl"); 30 | 31 | // we also need a special uniform interface here to pass the texture to the shader 32 | #[derive(Uniforms)] 33 | struct ShaderUniforms { 34 | tex: Uni>, 35 | } 36 | 37 | pub struct LocalExample { 38 | texture: Texture, 39 | program: Program<(), (), TriangleFan, FragSlot, ShaderUniforms>, 40 | vertex_entity: VertexEntity<(), TriangleFan, ()>, 41 | back_buffer: Framebuffer, Back<()>>, 42 | } 43 | 44 | impl Example for LocalExample { 45 | type Err = Error; 46 | 47 | const TITLE: &'static str = "Texture"; 48 | 49 | fn bootstrap( 50 | [width, height]: [u32; 2], 51 | platform: &mut impl PlatformServices, 52 | ctx: &mut Context, 53 | ) -> Result { 54 | let (img_size, img_texels) = load_img(platform).expect("image to display"); 55 | let texture = ctx.new_texture( 56 | img_size, 57 | Mipmaps::No, 58 | &TextureSampling::default(), 59 | &img_texels, 60 | )?; 61 | 62 | let program = ctx.new_program( 63 | ProgramBuilder::new() 64 | .add_vertex_stage(VS) 65 | .no_primitive_stage() 66 | .add_shading_stage(FS), 67 | )?; 68 | 69 | // we’ll use an attributeless render here to display a quad on the screen (two triangles); there 70 | // are over ways to cover the whole screen but this is easier for you to understand; the 71 | // TriangleFan creates triangles by connecting the third (and next) vertex to the first one 72 | let vertex_entity = ctx.new_vertex_entity(VertexEntityBuilder::new())?; 73 | 74 | let back_buffer = ctx.back_buffer(Size2::new(width, height))?; 75 | 76 | Ok(LocalExample { 77 | texture, 78 | program, 79 | vertex_entity, 80 | back_buffer, 81 | }) 82 | } 83 | 84 | fn render_frame( 85 | mut self, 86 | _: f32, 87 | actions: impl Iterator, 88 | ctx: &mut Context, 89 | ) -> Result, Self::Err> { 90 | for action in actions { 91 | match action { 92 | InputAction::Quit => return Ok(LoopFeedback::Exit), 93 | 94 | InputAction::Resized { width, height } => { 95 | self.back_buffer = ctx.back_buffer(Size2::new(width, height))?; 96 | } 97 | 98 | _ => (), 99 | } 100 | } 101 | 102 | let tex = &self.texture; 103 | let program = &self.program; 104 | let vertex_entity = &self.vertex_entity; 105 | let render_state = &RenderState::default().set_blending(BlendingMode::Combined(Blending { 106 | equation: Equation::Additive, 107 | src: Factor::SrcAlpha, 108 | dst: Factor::Zero, 109 | })); 110 | 111 | let in_use_texture = ctx.use_texture(tex)?; 112 | ctx.with_framebuffer(&self.back_buffer, &PipelineState::default(), |mut frame| { 113 | frame.with_program(program, |mut frame| { 114 | frame.update(|mut program, unis| program.set(&unis.tex, &in_use_texture))?; 115 | 116 | frame.with_render_state(render_state, |mut frame| { 117 | frame.render_vertex_entity(vertex_entity.view(..4)) 118 | }) 119 | }) 120 | })?; 121 | 122 | Ok(LoopFeedback::Continue(self)) 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /examples/common/src/uni-buffer-2d-vs.glsl: -------------------------------------------------------------------------------- 1 | in vec2 co; 2 | in vec3 color; 3 | 4 | out vec3 v_color; 5 | 6 | uniform Positions { 7 | vec2[100] p; 8 | } positions; 9 | 10 | void main() { 11 | gl_Position = vec4(co + positions.p[gl_InstanceID], 0., 1.); 12 | v_color = color; 13 | } 14 | -------------------------------------------------------------------------------- /examples/common/src/vertex_instancing.rs: -------------------------------------------------------------------------------- 1 | //! This program shows you how to do *vertex instancing*, the easy way. 2 | //! 3 | //! 4 | 5 | use crate::{ 6 | shared::{FragSlot, Instance, Vertex}, 7 | Example, InputAction, LoopFeedback, PlatformServices, 8 | }; 9 | use luminance::{ 10 | backend::{Backend, Error}, 11 | context::Context, 12 | dim::{Dim2, Size2}, 13 | framebuffer::{Back, Framebuffer}, 14 | pipeline::PipelineState, 15 | primitive::Triangle, 16 | render_state::RenderState, 17 | shader::{Program, ProgramBuilder}, 18 | vertex_entity::{VertexEntity, VertexEntityBuilder, View}, 19 | vertex_storage::{Interleaved, Interleaving}, 20 | }; 21 | 22 | const VS: &'static str = include_str!("instancing-vs.glsl"); 23 | const FS: &'static str = include_str!("instancing-fs.glsl"); 24 | 25 | // Only one triangle this time. 26 | const TRI_VERTICES: [Vertex; 3] = [ 27 | // triangle – an RGB one 28 | // 29 | Vertex::new( 30 | mint::Vector2 { x: 0.5, y: -0.5 }, 31 | mint::Vector3 { 32 | x: 0., 33 | y: 1., 34 | z: 0., 35 | }, 36 | ), 37 | Vertex::new( 38 | mint::Vector2 { x: 0., y: 0.5 }, 39 | mint::Vector3 { 40 | x: 0., 41 | y: 0., 42 | z: 1., 43 | }, 44 | ), 45 | Vertex::new( 46 | mint::Vector2 { x: -0.5, y: -0.5 }, 47 | mint::Vector3 { 48 | x: 1., 49 | y: 0., 50 | z: 0., 51 | }, 52 | ), 53 | ]; 54 | 55 | // Instances. We’ll be using five triangles. 56 | const INSTANCES: [Instance; 5] = [ 57 | Instance { 58 | position: mint::Vector2 { x: 0., y: 0. }, 59 | weight: 1., 60 | }, 61 | Instance { 62 | position: mint::Vector2 { x: -0.5, y: 0.5 }, 63 | weight: 1., 64 | }, 65 | Instance { 66 | position: mint::Vector2 { x: -0.25, y: -0.1 }, 67 | weight: 1., 68 | }, 69 | Instance { 70 | position: mint::Vector2 { x: 0.45, y: 0.25 }, 71 | weight: 1., 72 | }, 73 | Instance { 74 | position: mint::Vector2 { x: 0.6, y: -0.3 }, 75 | weight: 1., 76 | }, 77 | ]; 78 | 79 | pub struct LocalExample { 80 | program: Program, 81 | triangle: VertexEntity, 82 | back_buffer: Framebuffer, Back<()>>, 83 | } 84 | 85 | impl Example for LocalExample { 86 | type Err = Error; 87 | 88 | const TITLE: &'static str = "Vertex instancing"; 89 | 90 | fn bootstrap( 91 | [width, height]: [u32; 2], 92 | _: &mut impl PlatformServices, 93 | ctx: &mut Context, 94 | ) -> Result { 95 | let program = ctx.new_program( 96 | ProgramBuilder::new() 97 | .add_vertex_stage(VS) 98 | .no_primitive_stage() 99 | .add_shading_stage(FS), 100 | )?; 101 | 102 | let triangle = ctx.new_vertex_entity( 103 | VertexEntityBuilder::new() 104 | .add_vertices(Interleaved::new().set_vertices(TRI_VERTICES)) 105 | .add_instances(Interleaved::new().set_vertices(INSTANCES)), 106 | )?; 107 | 108 | let back_buffer = ctx.back_buffer(Size2::new(width, height))?; 109 | 110 | Ok(Self { 111 | program, 112 | triangle, 113 | back_buffer, 114 | }) 115 | } 116 | 117 | fn render_frame( 118 | mut self, 119 | t: f32, 120 | actions: impl Iterator, 121 | ctx: &mut Context, 122 | ) -> Result, Self::Err> { 123 | for action in actions { 124 | match action { 125 | InputAction::Quit => return Ok(LoopFeedback::Exit), 126 | 127 | _ => (), 128 | } 129 | } 130 | 131 | // make instances go boop boop by changing their weight dynamically 132 | let instances = self.triangle.instance_data().vertices_mut(); 133 | 134 | for (i, instance) in instances.iter_mut().enumerate() { 135 | let tcos = (t * (i + 1) as f32 * 0.5).cos().powf(2.); 136 | instance.weight = tcos; 137 | } 138 | 139 | ctx.update_instance_data(&mut self.triangle)?; 140 | 141 | let program = &self.program; 142 | let triangle = &self.triangle; 143 | 144 | ctx.with_framebuffer(&self.back_buffer, &PipelineState::default(), |mut frame| { 145 | frame.with_program(program, |mut frame| { 146 | frame.update(|mut update, _| update.query_set::("t", &t))?; 147 | 148 | frame.with_render_state(&RenderState::default(), |mut frame| { 149 | frame.render_vertex_entity(triangle.view(..).set_instance_count(5)) 150 | }) 151 | }) 152 | })?; 153 | 154 | Ok(LoopFeedback::Continue(self)) 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /examples/desktop/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-examples-desktop" 3 | version = "0.1.0" 4 | authors = ["Dimitri Sabadie "] 5 | description = "Stateless and type-safe graphics framework" 6 | keywords = ["stateless", "type-safe", "graphics", "luminance"] 7 | categories = ["rendering::graphics-api"] 8 | homepage = "https://github.com/phaazon/luminance-rs" 9 | repository = "https://github.com/phaazon/luminance-rs" 10 | documentation = "https://docs.rs/luminance" 11 | readme = "README.md" 12 | edition = "2021" 13 | rust-version = "1.65.0" 14 | 15 | [[bin]] 16 | name = "luminance-examples-desktop" 17 | path = "src/main.rs" 18 | 19 | [features] 20 | funtest = ["luminance-examples/funtest",] 21 | funtest-gl33-f64-uniform = ["luminance-examples/funtest-gl33-f64-uniform"] 22 | 23 | [dependencies] 24 | env_logger = "0.9.0" 25 | glfw = "0.45" 26 | image = "0.24.1" 27 | log = "0.4.11" 28 | luminance = { version = "0.48.0-dev", path = "../../luminance", features = ["mint"] } 29 | luminance-examples = { version = "0.1", path = "../common" } 30 | luminance-gl2 = { version = "0.20.0-dev", path = "../../luminance-gl2" } 31 | luminance-glfw = { version = "0.19.0-dev", path = "../../luminance-glfw" } 32 | structopt = "0.3.21" 33 | -------------------------------------------------------------------------------- /examples/desktop/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /examples/desktop/README.md: -------------------------------------------------------------------------------- 1 | # Luminance examples desktop implementation 2 | 3 | This directory holds the desktop implementation of the examples. 4 | 5 | ## Quick start 6 | 7 | Nothing specific to do, just run `cargo run -- -l` in `examples/desktop` to build the examples and list all the 8 | available examples you can run. An example is run by giving its name to the built binary, like so: 9 | 10 | ```sh 11 | cargo run hello-world 12 | ``` 13 | 14 | Some examples have _features_, such as loading textures. Those require a special argument to be passed when run: the 15 | `-t` argument for textures, for instance: 16 | 17 | ```sh 18 | cargo run -- -t /tmp/texture-test displacement-map 19 | ``` 20 | 21 | For examples using textures, it is highly recommended to compile in `--release` mode: 22 | 23 | ```sh 24 | cargo run --release -- -t /tmp/texture-test displacement-map 25 | ``` 26 | -------------------------------------------------------------------------------- /examples/desktop/src/platform.rs: -------------------------------------------------------------------------------- 1 | //! Platform services implementation. 2 | 3 | use crate::CLIOpts; 4 | use image::ImageError; 5 | use luminance_examples::PlatformServices; 6 | use std::{error::Error, fmt}; 7 | 8 | /// Desktop implementation of the [`PlatformServices`] API. 9 | #[derive(Debug)] 10 | pub struct DesktopPlatformServices { 11 | textures: Vec, 12 | } 13 | 14 | impl DesktopPlatformServices { 15 | pub fn new(cli_opts: CLIOpts) -> Self { 16 | let textures = cli_opts.textures; 17 | 18 | if textures.is_empty() { 19 | Self { 20 | textures: Vec::new(), 21 | } 22 | } else { 23 | let textures = textures 24 | .into_iter() 25 | .map(|path| { 26 | image::open(&path) 27 | .map(|img| img.flipv().to_rgb8()) 28 | .expect(&format!("image {}", path)) 29 | }) 30 | .collect(); 31 | 32 | Self { textures } 33 | } 34 | } 35 | } 36 | 37 | #[derive(Debug)] 38 | pub enum DesktopFetchError { 39 | NoMoreTexture, 40 | ImageError(ImageError), 41 | } 42 | 43 | impl fmt::Display for DesktopFetchError { 44 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 45 | match self { 46 | DesktopFetchError::NoMoreTexture => f.write_str("no more texture, sorry"), 47 | DesktopFetchError::ImageError(ref e) => write!(f, "cannot fetch texture: {}", e), 48 | } 49 | } 50 | } 51 | 52 | impl Error for DesktopFetchError {} 53 | 54 | impl From for DesktopFetchError { 55 | fn from(source: ImageError) -> Self { 56 | Self::ImageError(source) 57 | } 58 | } 59 | 60 | impl PlatformServices for DesktopPlatformServices { 61 | type FetchError = DesktopFetchError; 62 | 63 | fn fetch_texture(&mut self) -> Result { 64 | if self.textures.is_empty() { 65 | Err(DesktopFetchError::NoMoreTexture) 66 | } else { 67 | Ok(self.textures.remove(0)) // bit of a cost but for small textures who cares? 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /examples/web/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | -------------------------------------------------------------------------------- /examples/web/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-examples-web" 3 | version = "0.1.0" 4 | authors = ["Dimitri Sabadie "] 5 | description = "Stateless and type-safe graphics framework" 6 | keywords = ["stateless", "type-safe", "graphics", "luminance"] 7 | categories = ["rendering::graphics-api"] 8 | homepage = "https://github.com/phaazon/luminance-rs" 9 | repository = "https://github.com/phaazon/luminance-rs" 10 | documentation = "https://docs.rs/luminance" 11 | readme = "README.md" 12 | edition = "2021" 13 | rust-version = "1.65.0" 14 | 15 | [lib] 16 | crate-type = ["cdylib"] 17 | 18 | [features] 19 | funtest = ["luminance-examples/funtest"] 20 | 21 | [dependencies] 22 | console_error_panic_hook = "0.1.6" 23 | env_logger = "0.9.0" 24 | log = "0.4.11" 25 | luminance = { version = "0.47", path = "../../luminance" } 26 | luminance-examples = { version = "0.1", path = "../common" } 27 | luminance-front = { version = "0.6", path = "../../luminance-front" } 28 | luminance-web-sys = { version = "0.5", path = "../../luminance-web-sys" } 29 | wasm-bindgen = "0.2.63" 30 | wasm-logger = "0.2" 31 | 32 | [dependencies.image] 33 | version = "0.24.1" 34 | default-features = false 35 | features = ["gif", "jpeg", "ico", "png", "pnm", "tga", "tiff", "webp", "bmp", "hdr", "dxt", "dds", "farbfeld"] 36 | 37 | [dependencies.web-sys] 38 | version = "0.3.44" 39 | features = [ 40 | "Window", 41 | "console", 42 | ] 43 | -------------------------------------------------------------------------------- /examples/web/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /examples/web/README.md: -------------------------------------------------------------------------------- 1 | # Luminance examples Web implementation 2 | 3 | This directory holds the Web implementation of the examples. 4 | 5 | ## Quick start 6 | 7 | You must install all the `npm` dependencies before trying to run the examples. Run this in the `examples/web` directory 8 | (same as this README): 9 | 10 | ```sh 11 | yarn install 12 | ``` 13 | 14 | This will install all the dependencies needed to bundle a Web app gathering the example. You can then start a 15 | development server: 16 | 17 | ```sh 18 | yarn serve 19 | ``` 20 | 21 | If you want to give a try to examples that require fetching and loading textures, it is highly recommended to run in 22 | production mode. The reason for that is that `yarn serve` (or `yarn build`) will automatically ask 23 | `wasm-pack-plugin` to (re)compile the Rust code using release targets, greatly speeding up loading times (this is mostly 24 | due to the [image](https://crates.io/crates/image) crate): 25 | 26 | ```sh 27 | yarn serve --mode production 28 | ``` 29 | 30 | ## Run an example 31 | 32 | Once you have started the local server, head over to http://localhost:8080. You should be facing a white page with a 33 | drop-down list at the top-left of the page. That list contains all the available example. Selecting one will 34 | automatically bootstrap the example and run it. 35 | 36 | ### Featured examples: textures 37 | 38 | Some examples have special features, like being able to take _textures_ as input. The Web implementation uses the 39 | [Fetch API](https://developer.mozilla.org/fr/docs/Web/API/Fetch_API) to get them. When such an example requires you to 40 | pass a texture, you can currently pass the name of a texture that must live in the `examples/web/static` directory. So 41 | far, this is pretty limited and you will most of the time be required to give a static name to the texture (like 42 | `source.jpg`). This is subject to change later. 43 | 44 | > There is currently no way to fetch textures from the Internet because of CORS and because of _j’ai la flemme_. 45 | 46 | Once you have selected and submitted the name of the texture to use, the example should bootstrap, load the texture and 47 | run the actual code. 48 | -------------------------------------------------------------------------------- /examples/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "build": "webpack", 4 | "serve": "webpack-dev-server" 5 | }, 6 | "devDependencies": { 7 | "@wasm-tool/wasm-pack-plugin": "1.0.1", 8 | "html-webpack-plugin": "^3.2.0", 9 | "text-encoding": "^0.7.0", 10 | "webpack": "^4.43.0", 11 | "webpack-cli": "^3.3.12", 12 | "webpack-dev-server": "^3.1.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/web/src/platform.rs: -------------------------------------------------------------------------------- 1 | //! Platform services implementation. 2 | 3 | use image::ImageError; 4 | use luminance_examples::PlatformServices; 5 | use std::{error::Error, fmt}; 6 | 7 | /// Web implementation of the [`PlatformService`] API. 8 | #[derive(Debug)] 9 | pub struct WebPlatformServices { 10 | textures: Vec, 11 | } 12 | 13 | impl WebPlatformServices { 14 | pub fn new() -> Self { 15 | let textures = Vec::new(); 16 | Self { textures } 17 | } 18 | 19 | pub fn add_texture(&mut self, blob: Vec) { 20 | match image::load_from_memory(&blob) { 21 | Err(err) => log::error!("cannot read texture {}", err), 22 | Ok(img) => { 23 | log::info!("added a new texture"); 24 | self.textures.push(img.flipv().into_rgb8()); 25 | } 26 | } 27 | } 28 | } 29 | 30 | #[derive(Debug)] 31 | pub enum WebFetchError { 32 | NoMoreTexture, 33 | ImageError(ImageError), 34 | } 35 | 36 | impl fmt::Display for WebFetchError { 37 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 38 | match self { 39 | WebFetchError::NoMoreTexture => f.write_str("no more texture, sorry"), 40 | WebFetchError::ImageError(ref e) => write!(f, "cannot fetch texture: {}", e), 41 | } 42 | } 43 | } 44 | 45 | impl Error for WebFetchError {} 46 | 47 | impl From for WebFetchError { 48 | fn from(source: ImageError) -> Self { 49 | Self::ImageError(source) 50 | } 51 | } 52 | 53 | impl PlatformServices for WebPlatformServices { 54 | type FetchError = WebFetchError; 55 | 56 | fn fetch_texture(&mut self) -> Result { 57 | if self.textures.is_empty() { 58 | Err(WebFetchError::NoMoreTexture) 59 | } else { 60 | Ok(self.textures.remove(0)) // bit of a cost but for small textures who cares? 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /examples/web/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const webpack = require('webpack'); 4 | const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin"); 5 | 6 | module.exports = { 7 | entry: './index.js', 8 | output: { 9 | path: path.resolve(__dirname, 'dist'), 10 | filename: 'index.js', 11 | }, 12 | plugins: [ 13 | new HtmlWebpackPlugin(), 14 | new WasmPackPlugin({ 15 | crateDirectory: path.resolve(__dirname, "."), 16 | extraArgs: "-- --features funtest" 17 | }), 18 | // Have this example work in Edge which doesn't ship `TextEncoder` or 19 | // `TextDecoder` at this time. 20 | new webpack.ProvidePlugin({ 21 | TextDecoder: ['text-encoding', 'TextDecoder'], 22 | TextEncoder: ['text-encoding', 'TextEncoder'] 23 | }) 24 | ], 25 | mode: 'development', 26 | devServer: { 27 | contentBase: '.' 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /luminance-derive/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document is the changelog of [luminance-derive](https://crates.io/crates/luminance-derive). 4 | You should consult it when upgrading to a new version, as it contains precious information on 5 | breaking changes, minor additions and patch notes. 6 | 7 | **If you’re experiencing weird type errors when upgrading to a new version**, it might be due to 8 | how `cargo` resolves dependencies. `cargo update` is not enough, because all luminance crate use 9 | [SemVer ranges](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) to stay 10 | compatible with as many crates as possible. In that case, you want `cargo update --aggressive`. 11 | 12 | # 0.10 13 | 14 | > Apr 12, 2022 15 | 16 | - Remove `Vertex::ATTR_COUNT` — it’s now computed based on the attributes directly. 17 | 18 | # 0.9 19 | 20 | > Dec 31, 2021 21 | 22 | - Support of `luminance-0.46`. 23 | 24 | # 0.8 25 | 26 | > Nov 26, 2021 27 | 28 | - Support of `luminance-0.45`. 29 | 30 | # 0.7 31 | 32 | > Apr 25, 2021 33 | 34 | - Support of `luminance-0.44`. 35 | - Add a check when a `Vertex` type has fields of the same type and raise a compile-time error if that’s the case. 36 | - Remove the `dev-dependencies` entry on `luminance`. This is was needed for tests only, which were moved to `luminance` 37 | directly, and the cycle dependency was preventing from releasing major bumps of crates. 38 | 39 | # 0.6.3 40 | 41 | > Oct 28, 2020 42 | 43 | - Support of `luminance-0.43`. 44 | 45 | # 0.6.2 46 | 47 | > Aug 30th, 2020 48 | 49 | - Support of `luminance-0.42`. 50 | 51 | # 0.6.1 52 | 53 | > Jul 24th, 2020 54 | 55 | - Support of `luminance-0.41`. 56 | 57 | # 0.6 58 | 59 | > Wed Jul, 15th 2020 60 | 61 | - The `UniformInterface` proc-macro got patched to adapt to the new backend architecture. 62 | - Implement `std::error::Error` for various types of the crate. 63 | - Add helper methods to create error types requiring owned data via a better API. 64 | 65 | # 0.5.2 66 | 67 | > Tue Jan, 7th 2020 68 | 69 | - Add `Deref` and `DerefMut` implementors for semantics’ generated variant types. You can now 70 | access the underlying (wrapped) repr type. 71 | - In the case of `Deref` and `DerefMut` not being enough, the underlying field can also be 72 | directly accessed (it’s now `pub`). 73 | 74 | # 0.5.1 75 | 76 | > Sat Jan, 4th 2020 77 | 78 | - Support of `luminance-0.38`. 79 | 80 | # 0.5 81 | 82 | > Sun Sep, 29th 2019 83 | 84 | - Support of `luminance-0.37`. 85 | 86 | # 0.4 87 | 88 | > Fri Sep, 20th 2019 89 | 90 | ## Major changes 91 | 92 | - Add `new` methods for types annotated with `Vertex`. This is considered a breaking change as 93 | it would break your code if you already have a `new` method, which is very likely. 94 | 95 | ## Minor changes 96 | 97 | - Add support for struct-tuple when deriving `Vertex`. 98 | 99 | ## Patch changes 100 | 101 | - Empty `Semantics` types are forbidden and now reported correctly as errors. 102 | 103 | # 0.3 104 | 105 | > Thur Sep, 12th 2019 106 | 107 | - Fix SemVer issues with ranges and duplicated dependencies. 108 | 109 | # 0.2.2 110 | 111 | > Thur Sep, 12th 2019 112 | 113 | - Support of `luminance-0.35`. 114 | 115 | # 0.2.1 116 | 117 | > Wed Sep, 11th 2019 118 | 119 | - Support of `luminance-0.34`. 120 | 121 | # 0.2 122 | 123 | > Fri Sep, 6th 2019 124 | 125 | - Support of `luminance-0.33`. 126 | 127 | # 0.1.1 128 | 129 | > Tue Sep, 3rd 2019 130 | 131 | - Support of `luminance-0.32`. 132 | 133 | # 0.1 134 | 135 | > Fri Aug, 23th 2019 136 | 137 | - Initial revision. 138 | -------------------------------------------------------------------------------- /luminance-derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-derive" 3 | version = "0.11.0-dev" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "Procedural macros for deriving luminance traits" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance", "derive"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-derive" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [lib] 20 | proc-macro = true 21 | 22 | [dependencies] 23 | proc-macro2 = "1" 24 | quote = "1" 25 | syn = { version = "1", features = ["extra-traits"] } 26 | -------------------------------------------------------------------------------- /luminance-derive/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-derive/README.md: -------------------------------------------------------------------------------- 1 | # luminance-derive 2 | 3 | 4 | 5 | Derive procedural macros for [luminance]. 6 | 7 | This crate exports several macros used to ease development with [luminance]. You are 8 | strongly advised to read the documentation of [luminance] in the first place. 9 | 10 | # `Vertex` 11 | 12 | This macro allows to derive the [`Vertex`] trait for a custom `struct` type. 13 | 14 | [See the full documentation here](https://docs.rs/luminance/latest/luminance/#vertex) 15 | 16 | # `Semantics` 17 | 18 | This macro allows to derive the [`Semantics`] trait for a custom `enum` type. 19 | 20 | [See the full documentation here](https://docs.rs/luminance/latest/luminance/#semantics) 21 | 22 | # `UniformInterface` 23 | 24 | This macro allows to derive the [`UniformInterface`] trait for a custom `struct` type. 25 | 26 | [See the full documentation here](https://docs.rs/luminance/latest/luminance/#uniform-interface) 27 | 28 | [luminance]: https://crates.io/crates/luminance 29 | [`Vertex`]: https://docs.rs/luminance/latest/luminance/vertex/trait.Vertex.html 30 | [`Semantics`]: https://docs.rs/luminance/latest/luminance/vertex/trait.Semantics.html 31 | 32 | 33 | -------------------------------------------------------------------------------- /luminance-derive/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(const_cmp, proc_macro_diagnostic)] 2 | 3 | mod attrib; 4 | mod memory_layout; 5 | mod render_slots; 6 | mod uniforms; 7 | mod vertex; 8 | 9 | use crate::vertex::generate_vertex_impl; 10 | use crate::{render_slots::impl_render_slots, uniforms::generate_uniforms_impl}; 11 | use memory_layout::{impl_memory_layout, Layout}; 12 | use proc_macro::TokenStream; 13 | use syn::{self, parse_macro_input, Data, DeriveInput}; 14 | 15 | #[proc_macro_derive(Vertex, attributes(vertex))] 16 | pub fn derive_vertex(input: TokenStream) -> TokenStream { 17 | let di: DeriveInput = parse_macro_input!(input); 18 | 19 | match di.data { 20 | // for now, we only handle structs 21 | Data::Struct(struct_) => match generate_vertex_impl(di.ident, di.attrs.iter(), struct_) { 22 | Ok(impl_) => impl_, 23 | Err(e) => panic!("{}", e), 24 | }, 25 | 26 | _ => panic!("only structs are currently supported for deriving Vertex"), 27 | } 28 | } 29 | 30 | #[proc_macro_derive(Uniforms, attributes(uniform))] 31 | pub fn derive_uniforms(input: TokenStream) -> TokenStream { 32 | let di: DeriveInput = parse_macro_input!(input); 33 | 34 | match di.data { 35 | // for now, we only handle structs 36 | Data::Struct(struct_) => match generate_uniforms_impl(di.ident, struct_) { 37 | Ok(impl_) => impl_, 38 | Err(e) => panic!("{}", e), 39 | }, 40 | 41 | _ => panic!("only structs are currently supported for deriving Uniforms"), 42 | } 43 | } 44 | 45 | #[proc_macro_derive(RenderSlots, attributes(slot))] 46 | pub fn derive_render_slots(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 47 | let item: DeriveInput = parse_macro_input!(input); 48 | impl_render_slots(item).into() 49 | } 50 | 51 | #[proc_macro_derive(Std140)] 52 | pub fn derive_std140(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 53 | let item: DeriveInput = parse_macro_input!(input); 54 | impl_memory_layout(item, Layout::Std140).into() 55 | } 56 | 57 | #[proc_macro_derive(Std430)] 58 | pub fn derive_std430(input: proc_macro::TokenStream) -> proc_macro::TokenStream { 59 | let item: DeriveInput = parse_macro_input!(input); 60 | impl_memory_layout(item, Layout::Std430).into() 61 | } 62 | -------------------------------------------------------------------------------- /luminance-derive/src/memory_layout.rs: -------------------------------------------------------------------------------- 1 | //! Implementation of the derive proc-macros for [`Std140`] and [`Std430`]. 2 | 3 | use proc_macro::{Diagnostic, Level}; 4 | use proc_macro2::{Ident, Span, TokenStream}; 5 | use quote::quote; 6 | use syn::DeriveInput; 7 | 8 | pub enum Layout { 9 | Std140, 10 | Std430, 11 | } 12 | 13 | pub fn impl_memory_layout(item: DeriveInput, layout: Layout) -> TokenStream { 14 | match item.data { 15 | syn::Data::Struct(data) => { 16 | let (field_ctors, field_decls, off, mut max_align) = 17 | data 18 | .fields 19 | .iter() 20 | .fold((Vec::new(), Vec::new(), quote!{ 0 }, quote!{ 0 }), |(mut field_ctors, mut field_decls, off, max_align), field| { 21 | let field_ident = field.ident.as_ref().unwrap(); 22 | let pad_field_name = Ident::new(&format!("_pad_{}", field_ident), Span::call_site()); 23 | let field_ty = &field.ty; 24 | let field_align = quote! { <#field_ty as luminance::shader::MemoryAlign>::ALIGNMENT }; 25 | let pad_size = quote! { (#field_align - (#off) % #field_align) % #field_align }; 26 | 27 | // how to build those fields; padding then actual field 28 | field_ctors.push(quote! { #pad_field_name: [0; #pad_size] }); 29 | field_ctors.push(quote! { #field_ident: s.#field_ident }); 30 | 31 | // add padding to the list of fields 32 | field_decls.push(quote!{ #pad_field_name: [u8; #pad_size] }); 33 | 34 | // add the regular field 35 | field_decls.push(quote!{ #field }); 36 | 37 | // compute the new offset and new max_align 38 | let max_align = quote! { std::cmp::max(#max_align, #field_align) }; 39 | let off = quote! { #off + #pad_size + std::mem::size_of::<#field_ty>() }; 40 | 41 | (field_ctors, field_decls, off, max_align) 42 | }); 43 | 44 | // the alignment of the struct must be rounded up to the aligment of a vec4 (16 bytes); this is only there for 45 | // Std140; Std430 doesn’t have that restriction (same for arrays) 46 | let struct_ident = &item.ident; 47 | let memory_layout; 48 | let aligned_ident; 49 | if let Layout::Std140 = layout { 50 | max_align = quote! { ((#max_align + 15) & !15) }; 51 | memory_layout = quote! { luminance::shader::Std140 }; 52 | aligned_ident = Ident::new(&format!("{}Std140", struct_ident), Span::call_site()); 53 | } else { 54 | memory_layout = quote! { luminance::shader::Std430 }; 55 | aligned_ident = Ident::new(&format!("{}Std430", struct_ident), Span::call_site()); 56 | } 57 | 58 | let struct_padding = quote! { (#max_align - (#off) % #max_align) % #max_align }; 59 | 60 | quote! { 61 | #[repr(C)] 62 | pub struct #aligned_ident { 63 | #(#field_decls ,)* 64 | 65 | // last padding, if any 66 | _pad_struct: [u8; #struct_padding], 67 | } 68 | 69 | impl From<#struct_ident> for #aligned_ident { 70 | fn from(s: #struct_ident) -> Self { 71 | #aligned_ident { 72 | #(#field_ctors ,)* 73 | 74 | _pad_struct: [0; #struct_padding], 75 | } 76 | } 77 | } 78 | 79 | unsafe impl luminance::shader::MemoryLayout<#memory_layout> for #struct_ident { 80 | type Aligned = #aligned_ident; 81 | } 82 | } 83 | } 84 | 85 | syn::Data::Enum(_) => { 86 | Diagnostic::new(Level::Error, "cannot implement MemoryLayout for enum").emit(); 87 | proc_macro2::TokenStream::new() 88 | } 89 | 90 | syn::Data::Union(_) => { 91 | Diagnostic::new(Level::Error, "cannot implement MemoryLayout for union").emit(); 92 | proc_macro2::TokenStream::new() 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /luminance-derive/src/render_slots.rs: -------------------------------------------------------------------------------- 1 | //! Implementation of the derive proc-macro for `RenderSlots`. 2 | 3 | use proc_macro::{Diagnostic, Level}; 4 | use proc_macro2::{Span, TokenStream}; 5 | use quote::quote; 6 | use syn::{DeriveInput, Ident}; 7 | 8 | pub fn impl_render_slots(item: DeriveInput) -> TokenStream { 9 | let type_ident = &item.ident; 10 | 11 | match item.data { 12 | syn::Data::Struct(data) => { 13 | let per_channel = data 14 | .fields 15 | .iter() 16 | .enumerate() 17 | .map(|(rank, field)| { 18 | let field_ident = field.ident.as_ref().expect("field ident"); 19 | let field_name = field_ident.to_string(); 20 | let field_ty = &field.ty; 21 | 22 | let impl_has_field = quote! { 23 | impl luminance::has_field::HasField<#field_name> for #type_ident { 24 | type FieldType = #field_ty; 25 | } 26 | }; 27 | 28 | let has_field_trait_bound = quote! { 29 | luminance::has_field::HasField<#field_name, FieldType = #field_ty> 30 | }; 31 | 32 | let render_layer_field = quote! { 33 | pub #field_ident: luminance::texture::Texture 34 | }; 35 | 36 | let render_layer_decl = quote! { 37 | #field_ident: backend.new_render_layer( 38 | framebuffer_handle, 39 | size, 40 | mipmaps, 41 | sampling, 42 | #rank, 43 | )? 44 | }; 45 | 46 | let render_channel_desc = quote! { 47 | luminance::render_slots::RenderChannelDesc { 48 | name: #field_name, // TODO: we need to be able to change that with #[???(name = "something else"] 49 | fmt: <#field_ty as luminance::pixel::Pixel>::PIXEL_FMT, 50 | } 51 | }; 52 | 53 | ( 54 | impl_has_field, 55 | has_field_trait_bound, 56 | render_layer_field, 57 | render_layer_decl, 58 | render_channel_desc, 59 | ) 60 | }) 61 | .collect::>(); 62 | let has_field_impls = per_channel.iter().map(|f| &f.0); 63 | let has_field_trait_bounds = per_channel.iter().map(|f| &f.1); 64 | let render_layer_fields = per_channel.iter().map(|f| &f.2); 65 | let render_layer_decls = per_channel.iter().map(|f| &f.3); 66 | let render_channel_descs = per_channel.iter().map(|f| &f.4); 67 | 68 | let render_layers_ty = Ident::new(&format!("{}RenderLayers", type_ident), Span::call_site()); 69 | 70 | quote! { 71 | // implement HasField for all the fields 72 | #(#has_field_impls)* 73 | 74 | // implement CompatibleRenderSlots 75 | impl luminance::render_slots::CompatibleRenderSlots for #type_ident 76 | where S: luminance::render_slots::RenderSlots + #(#has_field_trait_bounds)+* 77 | { 78 | } 79 | 80 | // generate a type that will act as RenderSlots::RenderLayers 81 | pub struct #render_layers_ty where D: luminance::dim::Dimensionable { 82 | #(#render_layer_fields),* 83 | } 84 | 85 | // implement RenderSlots 86 | impl luminance::render_slots::RenderSlots for #type_ident { 87 | type RenderLayers = #render_layers_ty where D: luminance::dim::Dimensionable; 88 | 89 | fn color_channel_descs() -> &'static [luminance::render_slots::RenderChannelDesc] { 90 | &[#(#render_channel_descs),*] 91 | } 92 | 93 | unsafe fn new_render_layers( 94 | backend: &mut B, 95 | framebuffer_handle: usize, 96 | size: D::Size, 97 | mipmaps: luminance::texture::Mipmaps, 98 | sampling: &luminance::texture::TextureSampling, 99 | ) -> Result, luminance::backend::FramebufferError> 100 | where 101 | B: luminance::backend::FramebufferBackend, 102 | D: luminance::dim::Dimensionable, 103 | { 104 | Ok( 105 | #render_layers_ty { #( #render_layer_decls),* } 106 | ) 107 | } 108 | } 109 | } 110 | } 111 | 112 | syn::Data::Enum(_) => { 113 | Diagnostic::new(Level::Error, "cannot implement RenderSlots for enum").emit(); 114 | proc_macro2::TokenStream::new() 115 | } 116 | 117 | syn::Data::Union(_) => { 118 | Diagnostic::new(Level::Error, "cannot implement RenderSlots for union").emit(); 119 | proc_macro2::TokenStream::new() 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /luminance-front/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document is the changelog of [luminance-front](https://crates.io/crates/luminance-front). 4 | You should consult it when upgrading to a new version, as it contains precious information on 5 | breaking changes, minor additions and patch notes. 6 | 7 | **If you’re experiencing weird type errors when upgrading to a new version**, it might be due to 8 | how `cargo` resolves dependencies. `cargo update` is not enough, because all luminance crate use 9 | [SemVer ranges](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) to stay 10 | compatible with as many crates as possible. In that case, you want `cargo update --aggressive`. 11 | 12 | # 0.6.1 13 | 14 | > Apr 12, 2022 15 | 16 | - Support of `luminance-0.47`. 17 | 18 | # 0.6 19 | 20 | > Dec 31, 2021 21 | 22 | - Support of `luminance-0.46`. 23 | 24 | # 0.5 25 | 26 | > Nov 26, 2021 27 | 28 | - Update `Vertices`, `VerticesMut`, `Indices`, `IndicesMut`, `Instances` and `InstancesMut` to reflect the lifetime 29 | change that happened in `luminance`. 30 | - Export the `tess::View` trait, which was missing from the public interface. 31 | - Export the new `luminance::shader::types::*`. 32 | - Fix architecture-based detection. The current process is that if the target architecture is not 33 | `wasm32-unknown-unknown`, we use `luminance-gl`. So we don’t depend on the CPU architecture anymore. 34 | 35 | # 0.4 36 | 37 | > Apr 25, 2021 38 | 39 | - Support of `luminance-0.44`. 40 | - Support of `luminance-gl-0.17`. 41 | - Support of `luminance-webgl-0.4`. 42 | - Re-exported `luminance::scissor`. 43 | 44 | # 0.3.1 45 | 46 | > Oct 28, 2020 47 | 48 | - Support of `luminance-0.43`. 49 | - Support of `luminance-gl-0.16`. 50 | - Support of `luminance-webgl-0.3`. 51 | 52 | # 0.3 53 | 54 | > Aug 30th, 2020 55 | 56 | - Support of `luminance-0.42`. 57 | 58 | # 0.2.3 59 | 60 | > Jul 28th, 2020 61 | 62 | - Add the missing re-export `Render`. 63 | 64 | # 0.2.2 65 | 66 | > Jul 28th, 2020 67 | 68 | - Add the missing re-export `UniformInterface`. 69 | 70 | # 0.2.1 71 | 72 | > Jul 27th, 2020 73 | 74 | - Fix the default types of `Tess` and `TessBuilder` according to `luminance-0.41`. Those were 75 | missing while they shouldn’t. 76 | 77 | # 0.2 78 | 79 | > Jul 24th, 2020 80 | 81 | - Re-export missing symbols, such as `RenderGate`. 82 | - Fix the `Tessgate` -> `TessGate` symbol. 83 | - Support of `luminance-0.41`. 84 | 85 | # 0.1 86 | 87 | > Wed Jul, 15th 2020 88 | 89 | - Initial revision. 90 | -------------------------------------------------------------------------------- /luminance-front/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-front" 3 | version = "0.6.1" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "luminance re-exported with a backend picked at compile-time" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-front" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [features] 20 | default = ["autoselect"] 21 | autoselect = ["gl33", "webgl2"] # automatically pick the right backend depending on the compilation target 22 | gl33 = ["luminance-gl"] # OpenGL 3.3 backend 23 | gl33-GL_ARB_gpu_shader_fp64 = ["luminance-gl/GL_ARB_gpu_shader_fp64"] # 64-bit support 24 | webgl2 = ["luminance-webgl"] # WebGL2 backend 25 | 26 | [dependencies] 27 | luminance = { version = ">=0.46, <0.48", path = "../luminance" } 28 | 29 | [target.'cfg(not(target_family = "wasm"))'.dependencies] 30 | luminance-gl = { version = "0.19", path = "../luminance-gl", optional = true } 31 | 32 | [target.'cfg(target_family = "wasm")'.dependencies] 33 | luminance-webgl = { version = "0.6", path = "../luminance-webgl", optional = true } 34 | -------------------------------------------------------------------------------- /luminance-front/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-front/README.md: -------------------------------------------------------------------------------- 1 | # luminance-front 2 | 3 | 4 | 5 | [luminance], but with a backend type picked at compile-time. 6 | 7 | This crate re-exports _aliases_ to all [luminance] types, methods, and any kind of symbols 8 | requiring a backend type variable (typically written `B`) by selecting the proper type based on 9 | the platform you target and/or feature flags. Selection is done mainly automatically in the 10 | `Cargo.toml` file, and can customize on a per-target basis which backend you want to select. 11 | 12 | > Important note: the existence of this crate was made a need so that people who don’t care 13 | > about genericity can start using [luminance] without having to worry about backend 14 | > implementations. It’s the case for people writing small binaries, “final” graphics libraries 15 | > and/or 2D/3D/animation engines, etc. If you are writing a [luminance] middleware, please 16 | > stick to the [luminance] crate and its polymorphic types. 17 | 18 | Some symbols are re-exported even though they are not polymorphic in a backend type variable in 19 | [luminance]. That is only for convenience purposes. 20 | 21 | # Documentation 22 | 23 | Because this crate re-exports the content of [luminance], you are strongly advised to go read 24 | the documentation on [luminance]. Documentation will not be duplicated here. 25 | 26 | # How to setup 27 | 28 | For a starter experience, you have nothing specific to do: simply add `luminance-front` as a 29 | direct dependency and you should be good to go: 30 | 31 | ```rust 32 | [dependencies] 33 | luminance-front = "…" 34 | ``` 35 | 36 | This will select a _default_ backend implementation for the target you currently compile for. 37 | See the list of features below for further information. 38 | 39 | To switch target to use, you are advised to either put a `.cargo/config` file in a directory 40 | inside your project, or compile with the `--target` option. 41 | 42 | The default setup will provide a default implementation that should work great on as 43 | many machines as possible for all supported targets. If for some reason you want to pick another 44 | implementation (for instance an older version of WebGL, OpenGL or an experimental, more modern 45 | implementation), you will have to use specific platform features, such as `"gl33"`. 46 | 47 | ```rust 48 | [dependencies] 49 | luminance-front = { version = "…", no-default-features = true, features = ["gl33", "webgl2"] } 50 | ``` 51 | 52 | As you can see, you can specify features for different targets at the same time. Target 53 | features are checked in the `lib.rs`, so it’s possible to define both OpenGL and WebGL 54 | features at the same time. The current target will narrow down which one to use. 55 | 56 | ## List of features 57 | 58 | - _Default_: `["gl33", "webgl2"]`. 59 | - **OpenGL**: 60 | - `"gl33"`: OpenGL 3.3 implementation. 61 | - **WebGL 2**: 62 | - `"webgl2"`: WebGL 2 implementation. 63 | 64 | [luminance]: https://crates.io/crates/luminance 65 | 66 | 67 | -------------------------------------------------------------------------------- /luminance-front/src/context.rs: -------------------------------------------------------------------------------- 1 | pub use luminance::context::GraphicsContext; 2 | -------------------------------------------------------------------------------- /luminance-front/src/framebuffer.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub type Framebuffer = luminance::framebuffer::Framebuffer; 4 | pub use luminance::framebuffer::{FramebufferError, IncompleteReason}; 5 | -------------------------------------------------------------------------------- /luminance-front/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! [luminance], but with a backend type picked at compile-time. 2 | //! 3 | //! This crate re-exports _aliases_ to all [luminance] types, methods, and any kind of symbols 4 | //! requiring a backend type variable (typically written `B`) by selecting the proper type based on 5 | //! the platform you target and/or feature flags. Selection is done mainly automatically in the 6 | //! `Cargo.toml` file, and can customize on a per-target basis which backend you want to select. 7 | //! 8 | //! > Important note: the existence of this crate was made a need so that people who don’t care 9 | //! > about genericity can start using [luminance] without having to worry about backend 10 | //! > implementations. It’s the case for people writing small binaries, “final” graphics libraries 11 | //! > and/or 2D/3D/animation engines, etc. If you are writing a [luminance] middleware, please 12 | //! > stick to the [luminance] crate and its polymorphic types. 13 | //! 14 | //! Some symbols are re-exported even though they are not polymorphic in a backend type variable in 15 | //! [luminance]. That is only for convenience purposes. 16 | //! 17 | //! # Documentation 18 | //! 19 | //! Because this crate re-exports the content of [luminance], you are strongly advised to go read 20 | //! the documentation on [luminance]. Documentation will not be duplicated here. 21 | //! 22 | //! # How to setup 23 | //! 24 | //! For a starter experience, you have nothing specific to do: simply add `luminance-front` as a 25 | //! direct dependency and you should be good to go: 26 | //! 27 | //! ```ignore 28 | //! [dependencies] 29 | //! luminance-front = "…" 30 | //! ``` 31 | //! 32 | //! This will select a _default_ backend implementation for the target you currently compile for. 33 | //! See the list of features below for further information. 34 | //! 35 | //! To switch target to use, you are advised to either put a `.cargo/config` file in a directory 36 | //! inside your project, or compile with the `--target` option. 37 | //! 38 | //! The default setup will provide a default implementation that should work great on as 39 | //! many machines as possible for all supported targets. If for some reason you want to pick another 40 | //! implementation (for instance an older version of WebGL, OpenGL or an experimental, more modern 41 | //! implementation), you will have to use specific platform features, such as `"gl33"`. 42 | //! 43 | //! ```ignore 44 | //! [dependencies] 45 | //! luminance-front = { version = "…", no-default-features = true, features = ["gl33", "webgl2"] } 46 | //! ``` 47 | //! 48 | //! As you can see, you can specify features for different targets at the same time. Target 49 | //! features are checked in the `lib.rs`, so it’s possible to define both OpenGL and WebGL 50 | //! features at the same time. The current target will narrow down which one to use. 51 | //! 52 | //! ## List of features 53 | //! 54 | //! - _Default_: `["gl33", "webgl2"]`. 55 | //! - **OpenGL**: 56 | //! - `"gl33"`: OpenGL 3.3 implementation. 57 | //! - **WebGL 2**: 58 | //! - `"webgl2"`: WebGL 2 implementation. 59 | //! 60 | //! [luminance]: https://crates.io/crates/luminance 61 | 62 | pub mod context; 63 | pub mod framebuffer; 64 | pub mod pipeline; 65 | pub mod query; 66 | pub mod render_gate; 67 | pub mod shader; 68 | pub mod shading_gate; 69 | pub mod tess; 70 | pub mod tess_gate; 71 | pub mod texture; 72 | 73 | // re-export 74 | pub use luminance::blending; 75 | pub use luminance::depth_stencil; 76 | pub use luminance::face_culling; 77 | pub use luminance::pixel; 78 | pub use luminance::render_state; 79 | pub use luminance::scissor; 80 | pub use luminance::vertex; 81 | 82 | // select the backend type 83 | 84 | #[cfg(all(feature = "gl33", not(target_family = "wasm")))] 85 | pub type Backend = luminance_gl::GL33; 86 | 87 | #[cfg(all(feature = "webgl2", target_family = "wasm"))] 88 | pub type Backend = luminance_webgl::webgl2::WebGL2; 89 | -------------------------------------------------------------------------------- /luminance-front/src/pipeline.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub use luminance::pipeline::{ 4 | PipelineError, PipelineState, ShaderDataBinding, TextureBinding, Viewport, 5 | }; 6 | 7 | pub type Pipeline<'a> = luminance::pipeline::Pipeline<'a, Backend>; 8 | pub type PipelineGate<'a> = luminance::pipeline::PipelineGate<'a, Backend>; 9 | pub type BoundTexture<'a, D, P> = luminance::pipeline::BoundTexture<'a, Backend, D, P>; 10 | pub type BoundShaderData<'a, T> = luminance::pipeline::BoundShaderData<'a, Backend, T>; 11 | pub type Render = luminance::pipeline::Render; 12 | -------------------------------------------------------------------------------- /luminance-front/src/query.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub type Query<'a> = luminance::query::Query<'a, Backend>; 4 | -------------------------------------------------------------------------------- /luminance-front/src/render_gate.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub type RenderGate<'a> = luminance::render_gate::RenderGate<'a, Backend>; 4 | -------------------------------------------------------------------------------- /luminance-front/src/shader.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub mod types; 4 | 5 | pub use luminance::shader::{ 6 | ProgramError, ProgramWarning, ShaderDataError, StageError, StageType, TessellationStages, 7 | Uniform, UniformInterface, UniformType, UniformWarning, VertexAttribWarning, 8 | }; 9 | 10 | pub type Stage = luminance::shader::Stage; 11 | pub type UniformBuilder<'a> = luminance::shader::UniformBuilder<'a, Backend>; 12 | pub type BuiltProgram = luminance::shader::BuiltProgram; 13 | pub type AdaptationFailure = 14 | luminance::shader::AdaptationFailure; 15 | pub type ProgramInterface<'a> = luminance::shader::ProgramInterface<'a, Backend>; 16 | pub type Program = luminance::shader::Program; 17 | pub type ShaderData = luminance::shader::ShaderData; 18 | -------------------------------------------------------------------------------- /luminance-front/src/shader/types.rs: -------------------------------------------------------------------------------- 1 | pub use luminance::shader::types::{Mat22, Mat33, Mat44, Vec2, Vec3, Vec4}; 2 | -------------------------------------------------------------------------------- /luminance-front/src/shading_gate.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub type ShadingGate<'a> = luminance::shading_gate::ShadingGate<'a, Backend>; 4 | -------------------------------------------------------------------------------- /luminance-front/src/tess.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub use luminance::vertex_entity::{ 4 | Deinterleaved, DeinterleavedData, Interleaved, Mode, TessError, TessIndexType, TessMapError, 5 | TessViewError, View, 6 | }; 7 | 8 | pub type TessBuilder<'a, V, I = (), W = (), S = Interleaved> = 9 | luminance::vertex_entity::TessBuilder<'a, Backend, V, I, W, S>; 10 | pub type Tess = 11 | luminance::vertex_entity::Tess; 12 | pub type Vertices<'a, V, I, W, S, T> = 13 | luminance::vertex_entity::Vertices<'a, Backend, V, I, W, S, T>; 14 | pub type VerticesMut<'a, V, I, W, S, T> = 15 | luminance::vertex_entity::VerticesMut<'a, Backend, V, I, W, S, T>; 16 | pub type Indices<'a, V, I, W, S> = luminance::vertex_entity::Indices<'a, Backend, V, I, W, S>; 17 | pub type IndicesMut<'a, V, I, W, S> = luminance::vertex_entity::IndicesMut<'a, Backend, V, I, W, S>; 18 | pub type Instances<'a, V, I, W, S, T> = 19 | luminance::vertex_entity::Instances<'a, Backend, V, I, W, S, T>; 20 | pub type InstancesMut<'a, V, I, W, S, T> = 21 | luminance::vertex_entity::InstancesMut<'a, Backend, V, I, W, S, T>; 22 | pub type TessView<'a, V, I, W, S> = luminance::vertex_entity::TessView<'a, Backend, V, I, W, S>; 23 | -------------------------------------------------------------------------------- /luminance-front/src/tess_gate.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub type TessGate<'a> = luminance::tess_gate::TessGate<'a, Backend>; 4 | -------------------------------------------------------------------------------- /luminance-front/src/texture.rs: -------------------------------------------------------------------------------- 1 | use crate::Backend; 2 | 3 | pub use luminance::texture::{ 4 | CubeFace, Cubemap, Dim, Dim1, Dim1Array, Dim2, Dim2Array, Dim3, Dimensionable, MagFilter, 5 | MinFilter, Sampler, TexelUpload, TextureError, Wrap, 6 | }; 7 | 8 | pub type Texture = luminance::texture::Texture; 9 | -------------------------------------------------------------------------------- /luminance-gl/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document is the changelog of [luminance-gl](https://crates.io/crates/luminance-gl). 4 | You should consult it when upgrading to a new version, as it contains precious information on 5 | breaking changes, minor additions and patch notes. 6 | 7 | **If you’re experiencing weird type errors when upgrading to a new version**, it might be due to 8 | how `cargo` resolves dependencies. `cargo update` is not enough, because all luminance crate use 9 | [SemVer ranges](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) to stay 10 | compatible with as many crates as possible. In that case, you want `cargo update --aggressive`. 11 | 12 | # 0.19 13 | 14 | > Apr 12, 2022 15 | 16 | - Support of `luminance-0.47`. 17 | 18 | # 0.19 19 | 20 | > Dec 31, 2021 21 | 22 | - Enable depth writing if we clear depth. It’s important to prevent getting invalidated state from a previous 23 | `RenderState`. 24 | - Support `luminance-0.46`. 25 | 26 | # 0.18 27 | 28 | > Nov 26, 2021 29 | 30 | - Fix lifetime issue with slicing tessellation. 31 | - Add support for `ShaderData` via `Std140` (`luminance-std140`). 32 | - Implement the new `Uniformable` interface. 33 | - Support for uniform array and runtime-check them. 34 | - Document public symbols. 35 | - Support the new color clearing. 36 | - Implement the new `TexelUpload` interface. 37 | 38 | # 0.17 39 | 40 | > Jun 28, 2021 41 | 42 | - Support of `luminance-0.44` and its subsequent texture resizing and new texture creation interface. 43 | - Add null pointer check in the OpenGL 3.3 buffer code, transformed into runtime errors in case of issues mapping buffer 44 | for instance. 45 | - Use arrays instead of tuples for pixel encoding wherever it was applicable. 46 | - Support for the Query API. 47 | - Fix support for doubles (`f64`) in shader code. This is gated by `GL_ARB_gpu_shader_fp64` and is not enabled by default. 48 | 49 | # 0.16.1 50 | 51 | > Oct 31st, 2020 52 | 53 | - Fix a bug while getting the context’s initial value for the _depth write_ property (that one can change with 54 | `RenderState::set_depth_write`). 55 | 56 | # 0.16 57 | 58 | > Oct 28th, 2020 59 | 60 | ## Breaking changes 61 | 62 | - Remove the `obtain_slice` and `obtain_slice_mut` methods. If you were using them, please feel free to use the `Deref` 63 | and `DerefMut` interface instead. It prevents one extra layer of useless validation via `Result`, since backends will 64 | simply always return `Ok(slice)`. The validation process is done when accessing the slice, e.g. `Buffer::slice` and 65 | `Buffer::slice_mut`. 66 | 67 | # 0.15.1 68 | 69 | > Oct 26th, 2020 70 | 71 | - Add a bunch of `Debug` annotations. 72 | - Add support for _scissor test_ implementation. 73 | 74 | # 0.15 75 | 76 | > Aug 30th, 2020 77 | 78 | - Add the `GL_ARB_gpu_shader_fp64` feature gate, allowing to use `f64`-like shader uniforms. 79 | Textures are not currently supported. 80 | - Remove unnecessary type-erasure that was basically doing a no-op. 81 | - Add support for `UniformWarning::UnsupportedType`, which is raised when a uniform type is used by the client 82 | code while not supported by the backend implementation. 83 | 84 | # 0.14.1 85 | 86 | > Jul 24th, 2020 87 | 88 | - Support of `luminance-0.41`. 89 | 90 | # 0.14 91 | 92 | > Wed Jul 15th, 2020 93 | 94 | - Replace mipmap creation’s square calls with bitwise left shifts to speed up computing the sizes 95 | of mipmaps. 96 | - Implement `std::error::Error` for various types of the crate. 97 | - It is now possible to _reset_ (i.e. _invalidate_) the OpenGL GPU state via an `unsafe` method. 98 | Few to almost no user should have a need for this — if you find yourself using that feature, then 99 | it’s either you’re doing something wrong, or something is missing to luminance, or finally you 100 | have to interop with a foreign system like imgui. That last case is the reason why that feature 101 | was developed. You should not need it. 102 | - Texture unit state tracking has been enhanced to minimize the number of GPU texture units when a 103 | bind would occur. This small optimization might often mean that one to several textures will get 104 | bound once and no texture binding will occur unless a dynamic change occur that requires another 105 | texture unit. 106 | - Fix a potential double-free when a `Program` doesn’t link. 107 | 108 | # Pre 0.14 109 | 110 | - The crate was available on https://crates.io with a different scope. If you were using it, please update to 111 | the latest [luminance](https://crates.io/crates/luminance) architecture. 112 | -------------------------------------------------------------------------------- /luminance-gl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-gl" 3 | version = "0.19.1" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "OpenGL backends for luminance" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance", "opengl"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-gl" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [features] 20 | default = ["gl33"] 21 | gl33 = [] 22 | # OpenGL extensions 23 | GL_ARB_gpu_shader_fp64 = [] 24 | 25 | [dependencies] 26 | gl = "0.14" 27 | luminance = { version = "0.48.0-dev", path = "../luminance" } 28 | # luminance-std140 = { version = "0.2", path = "../luminance-std140" } 29 | -------------------------------------------------------------------------------- /luminance-gl/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-gl/README.md: -------------------------------------------------------------------------------- 1 | # luminance-gl 2 | 3 | 4 | 5 | OpenGL backends. 6 | 7 | This crate exportes [OpenGL](https://www.khronos.org/opengl/) backends for 8 | [luminance](https://crates.io/crates/luminance). This crate can be used via two mechanisms: 9 | 10 | - Automatically selected for you by [luminance-front](https://crates.io/crates/luminance-front). This is the option 11 | you should probably go to in most of the cases, where you want the compiler to pick the backend type for you 12 | without caring too much about it. 13 | - Manually picked. In this case, you will want to browse the content of this crate to use a _backend type_. 14 | 15 | 16 | -------------------------------------------------------------------------------- /luminance-gl/src/gl33.rs: -------------------------------------------------------------------------------- 1 | //! OpenGL 3.3 backend. 2 | //! 3 | //! This module implements an OpenGL 3.3 backend for luminance. The backend type is [`GL33`]. 4 | 5 | mod buffer; 6 | mod depth_stencil; 7 | mod framebuffer; 8 | mod pipeline; 9 | mod pixel; 10 | mod query; 11 | mod shader; 12 | mod state; 13 | mod tess; 14 | mod texture; 15 | mod vertex_restart; 16 | 17 | pub use self::state::GLState; 18 | pub use self::state::StateQueryError; 19 | use std::cell::RefCell; 20 | use std::rc::Rc; 21 | 22 | /// An OpenGL 3.3 backend. 23 | /// 24 | /// This type is to be used as a luminance backend type. It implements the whole public API. 25 | #[derive(Debug)] 26 | pub struct GL33 { 27 | pub(crate) state: Rc>, 28 | } 29 | 30 | impl GL33 { 31 | /// Create a new OpenGL 3.3 backend. 32 | pub fn new() -> Result { 33 | GLState::new().map(|state| GL33 { 34 | state: Rc::new(RefCell::new(state)), 35 | }) 36 | } 37 | 38 | /// Internal access to the backend state. 39 | /// 40 | /// # Unsafety 41 | /// 42 | /// This method is **highly unsafe** as it exposes the internals of the backend. Playing with it should be done with 43 | /// extreme caution. 44 | pub unsafe fn state(&self) -> &Rc> { 45 | &self.state 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /luminance-gl/src/gl33/depth_stencil.rs: -------------------------------------------------------------------------------- 1 | use gl::types::*; 2 | 3 | use luminance::depth_stencil::{Comparison, StencilOp}; 4 | 5 | pub(crate) fn comparison_to_glenum(dc: Comparison) -> GLenum { 6 | match dc { 7 | Comparison::Never => gl::NEVER, 8 | Comparison::Always => gl::ALWAYS, 9 | Comparison::Equal => gl::EQUAL, 10 | Comparison::NotEqual => gl::NOTEQUAL, 11 | Comparison::Less => gl::LESS, 12 | Comparison::LessOrEqual => gl::LEQUAL, 13 | Comparison::Greater => gl::GREATER, 14 | Comparison::GreaterOrEqual => gl::GEQUAL, 15 | } 16 | } 17 | 18 | pub(crate) fn glenum_to_comparison(a: GLenum) -> Option { 19 | match a { 20 | gl::NEVER => Some(Comparison::Never), 21 | gl::ALWAYS => Some(Comparison::Always), 22 | gl::EQUAL => Some(Comparison::Equal), 23 | gl::NOTEQUAL => Some(Comparison::NotEqual), 24 | gl::LESS => Some(Comparison::Less), 25 | gl::LEQUAL => Some(Comparison::LessOrEqual), 26 | gl::GREATER => Some(Comparison::Greater), 27 | gl::GEQUAL => Some(Comparison::GreaterOrEqual), 28 | _ => None, 29 | } 30 | } 31 | 32 | pub(crate) fn stencil_op_to_glenum(op: StencilOp) -> GLenum { 33 | match op { 34 | StencilOp::Keep => gl::KEEP, 35 | StencilOp::Zero => gl::ZERO, 36 | StencilOp::Replace => gl::REPLACE, 37 | StencilOp::Increment => gl::INCR, 38 | StencilOp::IncrementWrap => gl::INCR_WRAP, 39 | StencilOp::Decrement => gl::DECR, 40 | StencilOp::DecrementWrap => gl::DECR_WRAP, 41 | StencilOp::Invert => gl::INVERT, 42 | } 43 | } 44 | 45 | pub(crate) fn glenum_to_stencil_op(a: GLenum) -> Option { 46 | match a { 47 | gl::KEEP => Some(StencilOp::Keep), 48 | gl::ZERO => Some(StencilOp::Zero), 49 | gl::REPLACE => Some(StencilOp::Replace), 50 | gl::INCR => Some(StencilOp::Increment), 51 | gl::INCR_WRAP => Some(StencilOp::IncrementWrap), 52 | gl::DECR => Some(StencilOp::Decrement), 53 | gl::DECR_WRAP => Some(StencilOp::DecrementWrap), 54 | gl::INVERT => Some(StencilOp::Invert), 55 | _ => None, 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /luminance-gl/src/gl33/query.rs: -------------------------------------------------------------------------------- 1 | //! Query API implementation for OpenGL 3.3. 2 | 3 | use crate::GL33; 4 | use luminance::backend::query::{Query as QueryBackend, QueryError}; 5 | 6 | unsafe impl QueryBackend for GL33 { 7 | fn backend_author(&self) -> Result { 8 | let name = self.state.borrow_mut().get_vendor_name(); 9 | Ok(name) 10 | } 11 | 12 | fn backend_name(&self) -> Result { 13 | let name = self.state.borrow_mut().get_renderer_name(); 14 | Ok(name) 15 | } 16 | 17 | fn backend_version(&self) -> Result { 18 | let name = self.state.borrow_mut().get_gl_version(); 19 | Ok(name) 20 | } 21 | 22 | fn backend_shading_lang_version(&self) -> Result { 23 | let name = self.state.borrow_mut().get_glsl_version(); 24 | Ok(name) 25 | } 26 | 27 | fn max_texture_array_elements(&self) -> Result { 28 | let max = self.state.borrow_mut().get_max_texture_array_elements(); 29 | Ok(max) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /luminance-gl/src/gl33/vertex_restart.rs: -------------------------------------------------------------------------------- 1 | //! Vertex restart related features. 2 | //! 3 | //! Vertex restart is a technique that allows 4 | 5 | /// Whether or not vertex restart is enabled. 6 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 7 | pub enum VertexRestart { 8 | /// Vertex restart is enabled. 9 | On, 10 | /// Vertex restart is disabled. 11 | Off, 12 | } 13 | -------------------------------------------------------------------------------- /luminance-gl/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! OpenGL backends. 2 | //! 3 | //! This crate exportes [OpenGL](https://www.khronos.org/opengl/) backends for 4 | //! [luminance](https://crates.io/crates/luminance). This crate can be used via two mechanisms: 5 | //! 6 | //! - Automatically selected for you by [luminance-front](https://crates.io/crates/luminance-front). This is the option 7 | //! you should probably go to in most of the cases, where you want the compiler to pick the backend type for you 8 | //! without caring too much about it. 9 | //! - Manually picked. In this case, you will want to browse the content of this crate to use a _backend type_. 10 | 11 | pub mod gl33; 12 | 13 | pub use gl33::GL33; 14 | -------------------------------------------------------------------------------- /luminance-gl2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-gl2" 3 | version = "0.20.0-dev" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "OpenGL backends for luminance" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance", "opengl"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-gl" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [features] 20 | default = ["GL33"] 21 | GL33 = [] 22 | shader-f64 = [] 23 | 24 | [dependencies] 25 | gl = "0.14" 26 | log = { version = "0.4.17", optional = true } 27 | luminance = { version = "0.48.0-dev", path = "../luminance" } 28 | # luminance-std140 = { version = "0.2", path = "../luminance-std140" } 29 | mint = { version = "0.5.9", optional = true } 30 | -------------------------------------------------------------------------------- /luminance-gl2/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | mod log; 3 | 4 | #[cfg(feature = "GL33")] 5 | pub mod gl33; 6 | 7 | #[cfg(feature = "GL33")] 8 | pub use gl33::GL33; 9 | -------------------------------------------------------------------------------- /luminance-gl2/src/log.rs: -------------------------------------------------------------------------------- 1 | #[macro_export] 2 | macro_rules! trace { 3 | ($($a:tt)*) => { 4 | #[cfg(feature = "log")] 5 | log::trace!($($a)*) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /luminance-glfw/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-glfw" 3 | version = "0.19.0-dev" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "GLFW support for luminance" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance", "glfw"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-glfw" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [dependencies] 20 | gl = "0.14" 21 | glfw = { version = "0.45.0", default-features = false } 22 | luminance = { version = "0.48.0-dev", path = "../luminance" } 23 | luminance-gl2 = { version = "0.20.0-dev", path = "../luminance-gl2" } 24 | 25 | [features] 26 | default = ["glfw-sys"] 27 | all = ["glfw-sys"] 28 | glfw-sys = ["glfw/glfw-sys"] 29 | log-errors = [] 30 | -------------------------------------------------------------------------------- /luminance-glfw/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-glfw/README.md: -------------------------------------------------------------------------------- 1 | # luminance-glfw 2 | 3 | 4 | 5 | [GLFW](https://crates.io/crates/glfw) backend for [luminance](https://crates.io/crates/luminance). 6 | 7 | 8 | -------------------------------------------------------------------------------- /luminance-glfw/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! [GLFW](https://crates.io/crates/glfw) backend for [luminance](https://crates.io/crates/luminance). 2 | 3 | use glfw::{self, Glfw, InitError, Window, WindowEvent}; 4 | use luminance::context::Context; 5 | use luminance_gl2::GL33; 6 | use std::{error, fmt, os::raw::c_void, sync::mpsc::Receiver}; 7 | 8 | /// Error that can be risen while creating a surface. 9 | #[non_exhaustive] 10 | #[derive(Debug)] 11 | pub enum GlfwSurfaceError { 12 | /// Initialization of the surface went wrong. 13 | /// 14 | /// This variant exposes a **glfw** error for further information about what went wrong. 15 | InitError(InitError), 16 | 17 | /// Error with the backend. 18 | BackendError(String), 19 | 20 | /// User error. 21 | UserError(E), 22 | } 23 | 24 | impl fmt::Display for GlfwSurfaceError 25 | where 26 | E: fmt::Display, 27 | { 28 | fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { 29 | match self { 30 | GlfwSurfaceError::InitError(e) => write!(f, "initialization error: {}", e), 31 | GlfwSurfaceError::BackendError(reason) => write!(f, "backend error: {}", reason), 32 | GlfwSurfaceError::UserError(e) => write!(f, "user error: {}", e), 33 | } 34 | } 35 | } 36 | 37 | impl From for GlfwSurfaceError { 38 | fn from(e: InitError) -> Self { 39 | GlfwSurfaceError::InitError(e) 40 | } 41 | } 42 | 43 | impl error::Error for GlfwSurfaceError 44 | where 45 | E: 'static + error::Error, 46 | { 47 | fn source(&self) -> Option<&(dyn error::Error + 'static)> { 48 | match self { 49 | GlfwSurfaceError::InitError(e) => Some(e), 50 | GlfwSurfaceError::UserError(e) => Some(e), 51 | _ => None, 52 | } 53 | } 54 | } 55 | 56 | /// GLFW surface. 57 | /// 58 | /// This type is a helper that exposes two important concepts: the GLFW event receiver that you can use it with to 59 | /// poll events and the [`GL33Context`], which allows you to perform the rendering part. 60 | #[derive(Debug)] 61 | pub struct GlfwSurface { 62 | /// Wrapped GLFW events queue. 63 | pub events_rx: Receiver<(f64, WindowEvent)>, 64 | /// 65 | /// Wrapped GLFW window. 66 | pub window: Window, 67 | 68 | /// Wrapped luminance context. 69 | pub ctx: Context, 70 | } 71 | 72 | impl GlfwSurface { 73 | /// Initialize GLFW to provide a luminance context. 74 | pub fn new_gl33( 75 | create_window: impl FnOnce( 76 | &mut Glfw, 77 | ) 78 | -> Result<(Window, Receiver<(f64, WindowEvent)>), GlfwSurfaceError>, 79 | ) -> Result> { 80 | #[cfg(feature = "log-errors")] 81 | let error_cbk = glfw::LOG_ERRORS; 82 | #[cfg(not(feature = "log-errors"))] 83 | let error_cbk = glfw::FAIL_ON_ERRORS; 84 | 85 | let mut glfw = glfw::init(error_cbk)?; 86 | 87 | // OpenGL hints 88 | glfw.window_hint(glfw::WindowHint::OpenGlProfile( 89 | glfw::OpenGlProfileHint::Core, 90 | )); 91 | glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); 92 | glfw.window_hint(glfw::WindowHint::ContextVersionMajor(3)); 93 | glfw.window_hint(glfw::WindowHint::ContextVersionMinor(3)); 94 | 95 | let (mut window, events_rx) = create_window(&mut glfw)?; 96 | 97 | // init OpenGL 98 | gl::load_with(|s| window.get_proc_address(s) as *const c_void); 99 | 100 | let ctx = Context::new(GL33::new) 101 | .ok_or_else(|| GlfwSurfaceError::BackendError("unavailable OpenGL 3.3 state".to_owned()))?; 102 | let surface = GlfwSurface { 103 | events_rx, 104 | window, 105 | ctx, 106 | }; 107 | 108 | Ok(surface) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /luminance-glutin/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document is the changelog of [luminance-glutin](https://crates.io/crates/luminance-glutin). 4 | You should consult it when upgrading to a new version, as it contains precious information on 5 | breaking changes, minor additions and patch notes. 6 | 7 | **If you’re experiencing weird type errors when upgrading to a new version**, it might be due to 8 | how `cargo` resolves dependencies. `cargo update` is not enough, because all luminance crate use 9 | [SemVer ranges](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) to stay 10 | compatible with as many crates as possible. In that case, you want `cargo update --aggressive`. 11 | 12 | # 0.14.1 13 | 14 | > Apr 12, 2022 15 | 16 | - Support of `luminance-0.47`. 17 | 18 | # 0.14 19 | 20 | > Dec 31, 2021 21 | 22 | - Dependency bump: `glutin-0.28`. 23 | 24 | # 0.13 25 | 26 | > Nov 26, 2021 27 | 28 | - Support of `luminance-0.45`. 29 | 30 | # 0.12 31 | 32 | > Jun 28, 2021 33 | 34 | - Support of `luminance-0.44`. 35 | - Support of `glutin-0.27`. 36 | 37 | # 0.11.3 38 | 39 | > Feb 16, 2021 40 | 41 | - Support of `glutin-0.26`. 42 | 43 | # 0.11.2 44 | 45 | > Oct 28, 2020 46 | 47 | - Support of `luminance-0.43`. 48 | - Support of `luminance-gl-0.16`. 49 | 50 | # 0.11.1 51 | 52 | > Oct 24th, 2020 53 | 54 | - Support of `glutin-0.25`. 55 | 56 | # 0.11 57 | 58 | > Aug 30th, 2020 59 | 60 | - Support of `luminance-0.42`. 61 | - Support of `luminance-gl-0.15`. 62 | 63 | # 0.10.1 64 | 65 | > Jul 24th, 2020 66 | 67 | - Support of `luminance-0.41`. 68 | 69 | # 0.10 70 | 71 | > Wed Jul, 15th 2020 72 | 73 | - Support `glutin-0.24`. 74 | - Implement `std::error::Error` for various types of the crate. 75 | - Add helper methods to create error types requiring owned data via a better API. 76 | 77 | # 0.9 78 | 79 | > Sun Feb, 23rd 2020 80 | 81 | - Support `glutin-0.23`. 82 | 83 | # 0.8.2 84 | 85 | > Wed Jan, 8th 2020 86 | 87 | - Add `GlutinSurface::from_builders`. That function can be used to create a new window and OpenGL 88 | context by explicitly building those objects in closures. 89 | 90 | # 0.8.1 91 | 92 | > Mon Jan, 6th 2020 93 | 94 | - Add `Display` implementation for `GlutinError`. 95 | 96 | # 0.8 97 | 98 | > Mon Jan, 6th 2020 99 | 100 | ## Breaking changes 101 | 102 | - Rework the interface to make it easier for people to have access to all the underlying `glutin` 103 | types. 104 | - The `luminance-windowing` interface is now just use as convenience to create a windowed context. 105 | The `Surface` trait is not implemented anymore as it’s subject to be deprecated very soon. 106 | 107 | # 0.7 108 | 109 | > Sat Jan, 4th 2020 110 | 111 | - Support of `luminance-0.38`. 112 | - Re-export `glutin::MouseButton`. 113 | 114 | # 0.6.1 115 | 116 | > Tue Nov, 5th 2017 117 | 118 | - Expose more `glutin` symbols on the public interface. 119 | 120 | # 0.6 121 | 122 | > Sun Sep, 29th 2019 123 | 124 | - Support of `luminance-0.37`. 125 | 126 | # 0.5 127 | 128 | > Fri Sep, 20th 2019 129 | 130 | - `luminance-0.36` support. 131 | 132 | # 0.4 133 | 134 | > Thur Sep, 12th 2019 135 | 136 | - Fix SemVer issues with ranges and duplicated dependencies. 137 | 138 | # 0.3.1 139 | 140 | > Thur Sep, 12th 2019 141 | 142 | - Support of `luminance-0.35`. 143 | 144 | # 0.3 145 | 146 | > Wed Sep, 11th 2019 147 | 148 | - Support of `luminance-0.34`. 149 | 150 | # 0.2 151 | 152 | > Fri Sep, 6th 2019 153 | 154 | - Support of `luminance-0.33`. 155 | 156 | # 0.1.1 157 | 158 | > Tue Sep, 3rd 2019 159 | 160 | - Support of `luminance-0.32`. 161 | 162 | # 0.1 163 | 164 | > Fri Aug, 23th 2019 165 | 166 | - Initial revision. 167 | -------------------------------------------------------------------------------- /luminance-glutin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-glutin" 3 | version = "0.14.1" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "Glutin support for luminance" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance", "glutin"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-glutin" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [dependencies] 20 | gl = "0.14" 21 | glutin = { version = "0.28", default-features = false } 22 | luminance = { version = ">=0.46, <0.48", path = "../luminance" } 23 | luminance-gl = { version = "0.19", path = "../luminance-gl" } 24 | 25 | [features] 26 | default = ["x11", "wayland"] 27 | serde = ["glutin/serde"] 28 | x11 = ["glutin/x11"] 29 | wayland = ["glutin/wayland"] 30 | -------------------------------------------------------------------------------- /luminance-glutin/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-glutin/README.md: -------------------------------------------------------------------------------- 1 | # luminance-glutin 2 | 3 | 4 | 5 | The [glutin](https://crates.io/crates/glutin) platform crate for [luminance](https://crates.io/crates/luminance). 6 | 7 | 8 | -------------------------------------------------------------------------------- /luminance-sdl2/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document is the changelog of [luminance-sdl2](https://crates.io/crates/luminance-sdl2). 4 | You should consult it when upgrading to a new version, as it contains precious information on 5 | breaking changes, minor additions and patch notes. 6 | 7 | **If you’re experiencing weird type errors when upgrading to a new version**, it might be due to 8 | how `cargo` resolves dependencies. `cargo update` is not enough, because all luminance crate use 9 | [SemVer ranges](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) to stay 10 | compatible with as many crates as possible. In that case, you want `cargo update --aggressive`. 11 | 12 | # 0.5.1 13 | 14 | > Apr 12, 2022 15 | 16 | - Support of `luminance-0.47`. 17 | 18 | # 0.5 19 | 20 | > Dec 31, 2021 21 | 22 | - Support `luminance-0.46`. 23 | 24 | # 0.4 25 | 26 | > Nov 26, 2021 27 | 28 | - Add support for `luminance-0.45`. 29 | - Bump support of `sdl2-0.35.1`. 30 | 31 | # 0.3 32 | 33 | > Jun 28, 2021 34 | 35 | - Add support for `luminance-0.44`. 36 | - Add support for `luminance-gl-0.17`. 37 | 38 | # 0.2.2 39 | 40 | > Feb 14, 2021 41 | 42 | - Add `GL33Surface::window_mut`. 43 | 44 | # 0.2.1 45 | 46 | > Oct 28, 2020 47 | 48 | - Support of `luminance-0.43`. 49 | - Support of `luminance-gl-0.16`. 50 | 51 | # 0.2 52 | 53 | > Aug 30th, 2020 54 | 55 | - Support of `luminance-0.42`. 56 | - Support of `luminance-gl-0.15`. 57 | 58 | # 0.1.1 59 | 60 | > Jul 24th, 2020 61 | 62 | - Support of `luminance-0.41`. 63 | 64 | # 0.1 65 | 66 | > Wed Jul, 15th 2020 67 | 68 | - Initial revision. 69 | -------------------------------------------------------------------------------- /luminance-sdl2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-sdl2" 3 | version = "0.5.1" 4 | license = "BSD-3-Clause" 5 | authors = [ 6 | "Dimitri Sabadie ", 7 | "Joel Nordström " 8 | ] 9 | description = "SDL2 support for luminance" 10 | keywords = ["stateless", "type-safe", "graphics", "luminance", "sdl"] 11 | categories = ["rendering::graphics-api"] 12 | homepage = "https://github.com/phaazon/luminance-rs" 13 | repository = "https://github.com/phaazon/luminance-rs" 14 | documentation = "https://docs.rs/luminance-sdl2" 15 | readme = "README.md" 16 | edition = "2021" 17 | rust-version = "1.65.0" 18 | 19 | [badges] 20 | maintenance = { status = "actively-developed" } 21 | 22 | [features] 23 | default = ["bundled"] 24 | bundled = ["sdl2/bundled"] 25 | 26 | [dependencies] 27 | gl = "0.14" 28 | luminance = { version = ">=0.46, <0.48", path = "../luminance" } 29 | luminance-gl = { version = "0.19", path = "../luminance-gl" } 30 | sdl2 = "0.35.1" 31 | -------------------------------------------------------------------------------- /luminance-sdl2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-sdl2/README.md: -------------------------------------------------------------------------------- 1 | # luminance-sdl2 2 | 3 | > **Important notice**: The current status of the crate is on-pause because of 4 | > [rust-sdl2 #1029](https://github.com/Rust-SDL2/rust-sdl2/issues/1029). If you are willing to get updates of 5 | > `luminance-sdl2`, you are free to open a PR to update the code and make it work whatever the workaround. Because 6 | > [phaazon/luminance-rs] strives to test as much code as possible, every active crate should be tested and maintained. 7 | > This SDL2 crate doesn’t meet the standards because of its dependencies, so it’s currently and temporarily put aside. 8 | 9 | 10 | 11 | [SDL2](https://crates.io/crates/sdl2) backend for [luminance](https://crates.io/crates/luminance). 12 | 13 | 14 | 15 | [phaazon/luminance-rs]: https://github.com/phaazon/luminance-rs 16 | -------------------------------------------------------------------------------- /luminance-std140/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document is the changelog of [luminance-std140](https://crates.io/crates/luminance-std140). 4 | You should consult it when upgrading to a new version, as it contains precious information on 5 | breaking changes, minor additions and patch notes. 6 | 7 | **If you’re experiencing weird type errors when upgrading to a new version**, it might be due to 8 | how `cargo` resolves dependencies. `cargo update` is not enough, because all luminance crate use 9 | [SemVer ranges](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) to stay 10 | compatible with as many crates as possible. In that case, you want `cargo update --aggressive`. 11 | 12 | # 0.2.1 13 | 14 | > Apr 12, 2022 15 | 16 | - Support of `luminance-0.47`. 17 | 18 | # 0.2 19 | 20 | - ? 21 | 22 | # 0.1 23 | 24 | > Nov 26, 2021 25 | 26 | - Initial revision. 27 | -------------------------------------------------------------------------------- /luminance-std140/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-std140" 3 | version = "0.2.1" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "Std140 types and trait for OpenGL-based luminance backends" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance", "std140"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-std140" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [dependencies] 20 | luminance = { version = ">=0.46, <0.48", path = "../luminance" } 21 | -------------------------------------------------------------------------------- /luminance-std140/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-std140/README.md: -------------------------------------------------------------------------------- 1 | # luminance-std 2 | 3 | 4 | 5 | Types and traits implementing the [std140] OpenGL rule. 6 | 7 | [std140]: https://www.khronos.org/registry/OpenGL/specs/gl/glspec45.core.pdf#page=159 8 | 9 | 10 | -------------------------------------------------------------------------------- /luminance-web-sys/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | -------------------------------------------------------------------------------- /luminance-web-sys/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document is the changelog of [luminance-web-sys](https://crates.io/crates/luminance-web-sys). 4 | You should consult it when upgrading to a new version, as it contains precious information on 5 | breaking changes, minor additions and patch notes. 6 | 7 | **If you’re experiencing weird type errors when upgrading to a new version**, it might be due to 8 | how `cargo` resolves dependencies. `cargo update` is not enough, because all luminance crate use 9 | [SemVer ranges](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) to stay 10 | compatible with as many crates as possible. In that case, you want `cargo update --aggressive`. 11 | 12 | # 0.5.1 13 | 14 | > Apr 12, 2022 15 | 16 | - Support of `luminance-0.47`. 17 | 18 | # 0.5 19 | 20 | > Dec 31, 2021 21 | 22 | - Support of `luminance-0.46`. 23 | 24 | # 0.4 25 | 26 | > Nov 26, 2021 27 | 28 | - Support of `luminance-0.45`. 29 | - Remove useless dependency (`luminance-windowing`). 30 | 31 | # 0.3 32 | 33 | > Apr 25, 2021 34 | 35 | - Support of `luminance-0.44`. 36 | - Document `WebSysWebGL2Surface::from_canvas`. 37 | - Support opnengi WebGL context with parameters. 38 | 39 | # 0.2.3 40 | 41 | > Apr 20, 2021 42 | 43 | - Add `WebSysWebGL2Surface::from_canvas`. 44 | 45 | # 0.2.2 46 | 47 | > Oct 28th, 2020 48 | 49 | - Remove some warnings. 50 | 51 | # 0.2.1 52 | 53 | > Oct 28, 2020 54 | 55 | ## Patch 56 | 57 | - Support of `luminance-0.43`. 58 | - Support of `luminance-webgl-0.3`. 59 | 60 | ## Breaking changes 61 | 62 | - Remove the `WindowOpt` argument from `WebSysWebGL2Surface::new`. It was confusing people because most of its 63 | properties are held by the JavaScript object passed through wasm (typically, the canvas directly). If you were passing 64 | width and height via a `WindowOpt`, you can simply set those on the canvas JS-side directly. 65 | 66 | # 0.2 67 | 68 | > Aug 30th, 2020 69 | 70 | - Support of `luminance-0.42`. 71 | 72 | # 0.1.1 73 | 74 | > Jul 24th, 2020 75 | 76 | - Support of `luminance-0.41`. 77 | 78 | # 0.1 79 | 80 | > Wed Jul, 15th 2020 81 | 82 | - Initial revision. 83 | -------------------------------------------------------------------------------- /luminance-web-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-web-sys" 3 | version = "0.5.1" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "web-sys luminance platform" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance", "web-sys"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-web-sys" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [dependencies] 17 | luminance = { version = ">=0.46, <0.48", path = "../luminance" } 18 | luminance-webgl = { version = "0.6", path = "../luminance-webgl" } 19 | wasm-bindgen = "0.2.63" 20 | 21 | [dependencies.web-sys] 22 | version = "0.3.40" 23 | features = [ 24 | "Document", 25 | "Element", 26 | "HtmlCanvasElement", 27 | "WebGl2RenderingContext", 28 | "Window", 29 | ] 30 | -------------------------------------------------------------------------------- /luminance-web-sys/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-web-sys/README.md: -------------------------------------------------------------------------------- 1 | # luminance-web-sys 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /luminance-webgl/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | -------------------------------------------------------------------------------- /luminance-webgl/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | This document is the changelog of [luminance-webgl](https://crates.io/crates/luminance-webgl). 4 | You should consult it when upgrading to a new version, as it contains precious information on 5 | breaking changes, minor additions and patch notes. 6 | 7 | **If you’re experiencing weird type errors when upgrading to a new version**, it might be due to 8 | how `cargo` resolves dependencies. `cargo update` is not enough, because all luminance crate use 9 | [SemVer ranges](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) to stay 10 | compatible with as many crates as possible. In that case, you want `cargo update --aggressive`. 11 | 12 | # 0.6.1 13 | 14 | > Apr 12, 2022 15 | 16 | - Support of `luminance-0.47`. 17 | 18 | # 0.6 19 | 20 | - ? 21 | 22 | # 0.5.1 23 | 24 | > Dec 31, 2021 25 | 26 | - Enable depth writing if we clear depth. It’s important to prevent getting invalidated state from a previous 27 | `RenderState`. 28 | 29 | # 0.5 30 | 31 | > Nov 26, 2021 32 | 33 | - Fix buffer kind not correctly being used (i.e. mixing vertex and index buffers is not possible, for instance). This 34 | fix was the premise of the full fix, as a redesign of luminance’s buffer interface was needed to fully fix the problem. 35 | - Fix lifetime issue with slicing tessellation. 36 | - Add support for `ShaderData` via `Std140` (`luminance-std140`). 37 | - Implement the new `Uniformable` interface. 38 | - Support for uniform array and runtime-check them. 39 | - Support the new color clearing. 40 | - Implement the new `TexelUpload` interface. 41 | 42 | # 0.4 43 | 44 | > Apr 25, 2021 45 | 46 | - Support of `luminance-0.44` and its subsequent texture resizing and new texture creation interface. 47 | - Use arrays instead of tuples for pixel encoding wherever it was applicable. 48 | - Support for the Query API. 49 | - Fix WebGL `impl` for arrays to be able to use them as source of initial storage for `Buffer`. 50 | - Fix WebGL cubemap storage creation. The bug was making them completely unusable and highly distorted / corrupted. 51 | 52 | # 0.3.2 53 | 54 | > Oct 31st, 2020 55 | 56 | - Fix a bug while getting the context’s initial value for the _depth write_ property (that one can change with 57 | `RenderState::set_depth_write`). 58 | 59 | # 0.3.1 60 | 61 | > Oct 31st, 2020 62 | 63 | - Fix several uniform updates methods, that wouldn’t send data with the correct size, causing various random issues. 64 | 65 | # 0.3 66 | 67 | > Oct 28, 2020 68 | 69 | ## Patch 70 | 71 | - Remove the limitation about creating contexts in WebGL: it is now possible to create as many as users want. WebGL 72 | doesn’t have the same requirements as OpenGL in terms of threading and contexts. 73 | 74 | ## Breaking changes 75 | 76 | - Remove the `obtain_slice` and `obtain_slice_mut` methods. If you were using them, please feel free to use the `Deref` 77 | and `DerefMut` interface instead. It prevents one extra layer of useless validation via `Result`, since backends will 78 | simply always return `Ok(slice)`. The validation process is done when accessing the slice, e.g. `Buffer::slice` and 79 | `Buffer::slice_mut`. 80 | 81 | # 0.2.1 82 | 83 | > Oct 26th, 2020 84 | 85 | - Add a bunch of `Debug` annotations. 86 | - Add support for _scissor test_ implementation. 87 | 88 | # 0.2 89 | 90 | > Aug 30th, 2020 91 | 92 | - Support of `luminance-0.42`. 93 | - Add support for `UniformWarning::UnsupportedType`, which is raised when a uniform type is used by the client 94 | code while not supported by the backend implementation. 95 | 96 | # 0.1.2 97 | 98 | > Aug 18th, 2020 99 | 100 | - Remove unnecessary type-erasure that was basically doing a no-op. 101 | - Fix deinterleaved tessellation mapping that would map mutable slices with the wrong length. 102 | 103 | # 0.1.1 104 | 105 | > Jul 24th, 2020 106 | 107 | - Support of `luminance-0.41`. 108 | 109 | # 0.1 110 | 111 | > Wed Jul, 15th 2020 112 | 113 | - Initial revision. 114 | 115 | [luminance-webgl]: https://crates.io/crates/luminance-webgl 116 | -------------------------------------------------------------------------------- /luminance-webgl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance-webgl" 3 | version = "0.6.1" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "WebGL backend for luminance" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance", "webgl"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance-webgl" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [dependencies] 20 | luminance = { version = ">=0.46, <0.48", path = "../luminance" } 21 | luminance-std140 = { version = "0.2", path = "../luminance-std140" } 22 | serde = "1" 23 | serde_derive = "1" 24 | wasm-bindgen = "0.2.60" 25 | js-sys = "0.3.40" 26 | 27 | [dependencies.web-sys] 28 | version = "0.3.37" 29 | features = [ 30 | "WebGl2RenderingContext", 31 | "WebGlActiveInfo", 32 | "WebGlBuffer", 33 | "WebGlFramebuffer", 34 | "WebGlRenderbuffer", 35 | "WebGlProgram", 36 | "WebGlShader", 37 | "WebGlTexture", 38 | "WebGlUniformLocation", 39 | "WebGlVertexArrayObject", 40 | ] 41 | -------------------------------------------------------------------------------- /luminance-webgl/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance-webgl/README.md: -------------------------------------------------------------------------------- 1 | # luminance-webgl 2 | 3 | 4 | 5 | WebGL backend for luminance. 6 | 7 | This crate provides a [luminance] backend for [WebGL]. 8 | 9 | [luminance]: https://crates.io/crates/luminance 10 | [WebGL]: https://www.khronos.org/webgl 11 | 12 | 13 | -------------------------------------------------------------------------------- /luminance-webgl/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! WebGL backend for luminance. 2 | //! 3 | //! This crate provides a [luminance] backend for [WebGL]. 4 | //! 5 | //! [luminance]: https://crates.io/crates/luminance 6 | //! [WebGL]: https://www.khronos.org/webgl 7 | 8 | extern crate serde_derive; 9 | 10 | #[macro_use] 11 | mod slice; 12 | pub mod webgl2; 13 | 14 | pub use webgl2::WebGL2; 15 | -------------------------------------------------------------------------------- /luminance-webgl/src/slice.rs: -------------------------------------------------------------------------------- 1 | //! A small helper module to work with slices. 2 | 3 | /// A small helper to flatten a slice of arrays. Given a &[[T; N]], it returns a &[T], because 4 | /// there is no way to flatten slices of arrays in the standard library. 5 | /// 6 | /// Please do not abuse. 7 | macro_rules! flatten_slice { 8 | ($e:ident : $t:ty , len = $len:expr) => { 9 | std::slice::from_raw_parts($e.as_ptr() as *const $t, $len) 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /luminance-webgl/src/webgl2.rs: -------------------------------------------------------------------------------- 1 | //! WebGL 2.0 backend support. 2 | 3 | mod array_buffer; 4 | pub mod buffer; 5 | pub mod framebuffer; 6 | pub mod pipeline; 7 | pub mod pixel; 8 | pub mod query; 9 | pub mod shader; 10 | pub mod state; 11 | pub mod tess; 12 | pub mod texture; 13 | 14 | pub use crate::webgl2::array_buffer::IntoArrayBuffer; 15 | pub use crate::webgl2::state::StateQueryError; 16 | use crate::webgl2::state::WebGL2State; 17 | use std::cell::RefCell; 18 | use std::rc::Rc; 19 | use web_sys::WebGl2RenderingContext; 20 | 21 | /// The WebGL2 backend. 22 | #[derive(Debug)] 23 | pub struct WebGL2 { 24 | pub(crate) state: Rc>, 25 | } 26 | 27 | impl WebGL2 { 28 | pub fn new(ctx: WebGl2RenderingContext) -> Result { 29 | WebGL2State::new(ctx).map(|state| WebGL2 { 30 | state: Rc::new(RefCell::new(state)), 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /luminance-webgl/src/webgl2/array_buffer.rs: -------------------------------------------------------------------------------- 1 | //! A collection of utilities used to perform conversion between immutable slices and JavaScript’s 2 | //! various array types. 3 | 4 | /// Unsafe coercion to a `js_sys::Object` for immutable slices. 5 | /// 6 | /// This trait provides the [`into_array_buffer`] method, which is an unsafe operation, as 7 | /// the `view()` method, defined on the various arrays in the `js-sys` crate, requires that the 8 | /// underlying memory not be moved until the array is dropped. 9 | /// 10 | /// [`into_array_buffer`]: crate::webgl2::array_buffer::IntoArrayBuffer::into_array_buffer 11 | pub trait IntoArrayBuffer: Sized { 12 | /// Convert the input slice into a JavaScript object. 13 | /// 14 | /// # Unsafety 15 | /// 16 | /// The returned `Object` must not outlive the input slice, which memory must not be moved either. 17 | unsafe fn into_array_buffer(texels: &[Self]) -> js_sys::Object; 18 | } 19 | 20 | macro_rules! impl_IntoArrayBuffer { 21 | ($t:ty, $buffer:ty) => { 22 | impl IntoArrayBuffer for $t { 23 | unsafe fn into_array_buffer(texels: &[Self]) -> js_sys::Object { 24 | <$buffer>::view(texels).into() 25 | } 26 | } 27 | 28 | impl_tuple_IntoArrayBuffer!($t, ($t, $t), 2, $buffer); 29 | impl_tuple_IntoArrayBuffer!($t, ($t, $t, $t), 3, $buffer); 30 | impl_tuple_IntoArrayBuffer!($t, ($t, $t, $t, $t), 4, $buffer); 31 | 32 | impl_array_IntoArrayBuffer!($t, $buffer); 33 | }; 34 | } 35 | 36 | macro_rules! impl_tuple_IntoArrayBuffer { 37 | ($t:ty, $tuple:ty, $n:literal, $buffer:ty) => { 38 | // statically assert that [T; 3] has the same size as (T, T, T) 39 | // this checks that the from_raw_parts cast has the correct value for $n and $tuple 40 | const _: fn() = || { 41 | let _ = std::mem::transmute::<[$t; $n], $tuple>; 42 | }; 43 | 44 | impl IntoArrayBuffer for $tuple { 45 | unsafe fn into_array_buffer(texels: &[Self]) -> js_sys::Object { 46 | let slice: &[$t] = 47 | std::slice::from_raw_parts(texels.as_ptr() as *const $t, texels.len() * $n); 48 | 49 | <$buffer>::view(slice).into() 50 | } 51 | } 52 | }; 53 | } 54 | 55 | macro_rules! impl_array_IntoArrayBuffer { 56 | ($t:ty, $buffer:ty) => { 57 | impl IntoArrayBuffer for [$t; N] { 58 | unsafe fn into_array_buffer(texels: &[Self]) -> js_sys::Object { 59 | let slice: &[$t] = 60 | std::slice::from_raw_parts(texels.as_ptr() as *const $t, texels.len() * N); 61 | 62 | <$buffer>::view(slice).into() 63 | } 64 | } 65 | }; 66 | } 67 | 68 | impl_IntoArrayBuffer!(u8, js_sys::Uint8Array); 69 | impl_IntoArrayBuffer!(i8, js_sys::Int8Array); 70 | impl_IntoArrayBuffer!(u16, js_sys::Uint16Array); 71 | impl_IntoArrayBuffer!(i16, js_sys::Int16Array); 72 | impl_IntoArrayBuffer!(u32, js_sys::Uint32Array); 73 | impl_IntoArrayBuffer!(i32, js_sys::Int32Array); 74 | 75 | impl_IntoArrayBuffer!(f32, js_sys::Float32Array); 76 | impl_IntoArrayBuffer!(f64, js_sys::Float64Array); 77 | -------------------------------------------------------------------------------- /luminance-webgl/src/webgl2/query.rs: -------------------------------------------------------------------------------- 1 | //! Query API implementation. 2 | 3 | use crate::WebGL2; 4 | use luminance::backend::query::{Query as QueryBackend, QueryError}; 5 | 6 | unsafe impl QueryBackend for WebGL2 { 7 | fn backend_author(&self) -> Result { 8 | self 9 | .state 10 | .borrow_mut() 11 | .get_vendor_name() 12 | .ok_or_else(|| QueryError::NoBackendAuthor) 13 | } 14 | 15 | fn backend_name(&self) -> Result { 16 | self 17 | .state 18 | .borrow_mut() 19 | .get_renderer_name() 20 | .ok_or_else(|| QueryError::NoBackendName) 21 | } 22 | 23 | fn backend_version(&self) -> Result { 24 | self 25 | .state 26 | .borrow_mut() 27 | .get_webgl_version() 28 | .ok_or_else(|| QueryError::NoBackendVersion) 29 | } 30 | 31 | fn backend_shading_lang_version(&self) -> Result { 32 | self 33 | .state 34 | .borrow_mut() 35 | .get_glsl_version() 36 | .ok_or_else(|| QueryError::NoBackendShadingLanguageVersion) 37 | } 38 | 39 | fn max_texture_array_elements(&self) -> Result { 40 | self 41 | .state 42 | .borrow_mut() 43 | .get_max_texture_array_elements() 44 | .ok_or_else(|| QueryError::NoMaxTextureArrayElements) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /luminance/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "luminance" 3 | version = "0.48.0-dev" 4 | license = "BSD-3-Clause" 5 | authors = ["Dimitri Sabadie "] 6 | description = "Stateless and type-safe graphics framework" 7 | keywords = ["stateless", "type-safe", "graphics", "luminance"] 8 | categories = ["rendering::graphics-api"] 9 | homepage = "https://github.com/phaazon/luminance-rs" 10 | repository = "https://github.com/phaazon/luminance-rs" 11 | documentation = "https://docs.rs/luminance" 12 | readme = "README.md" 13 | edition = "2021" 14 | rust-version = "1.65.0" 15 | 16 | [badges] 17 | maintenance = { status = "actively-developed" } 18 | 19 | [features] 20 | default = ["luminance-derive"] 21 | shader-f64 = [] 22 | 23 | [dependencies] 24 | luminance-derive = { version = "0.11.0-dev", path = "../luminance-derive", optional = true } 25 | mint = { version = "0.5.9", optional = true } 26 | 27 | [dev-dependencies] 28 | mint = "0.5.9" 29 | -------------------------------------------------------------------------------- /luminance/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021, Dimitri Sabadie 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Dimitri Sabadie nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /luminance/src/blending.rs: -------------------------------------------------------------------------------- 1 | //! That module exports blending-related types and functions. 2 | //! 3 | //! Given two pixels *src* and *dst* – source and destination, we associate each pixel a blending 4 | //! factor – respectively, *srcK* and *dstK*. *src* is the pixel being computed, and *dst* is the 5 | //! pixel that is already stored in the framebuffer. 6 | //! 7 | //! The pixels can be blended in several ways. See the documentation of [`Equation`] for further 8 | //! details. 9 | //! 10 | //! The factors are encoded with [`Factor`]. 11 | //! 12 | //! [`Equation`]: crate::blending::Equation 13 | //! [`Factor`]: crate::blending::Factor 14 | 15 | /// Blending equation. Used to state how blending factors and pixel data should be blended. 16 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 17 | pub enum Equation { 18 | /// `Additive` represents the following blending equation: 19 | /// 20 | /// > `blended = src * srcK + dst * dstK` 21 | Additive, 22 | /// `Subtract` represents the following blending equation: 23 | /// 24 | /// > `blended = src * srcK - dst * dstK` 25 | Subtract, 26 | /// Because subtracting is not commutative, `ReverseSubtract` represents the following additional 27 | /// blending equation: 28 | /// 29 | /// > `blended = dst * dstK - src * srcK` 30 | ReverseSubtract, 31 | /// `Min` represents the following blending equation: 32 | /// 33 | /// > `blended = min(src, dst)` 34 | Min, 35 | /// `Max` represents the following blending equation: 36 | /// 37 | /// > `blended = max(src, dst)` 38 | Max, 39 | } 40 | 41 | /// Blending factors. Pixel data are multiplied by these factors to achieve several effects driven 42 | /// by *blending equations*. 43 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 44 | pub enum Factor { 45 | /// `1 * color = color` 46 | One, 47 | /// `0 * color = 0` 48 | Zero, 49 | /// `src * color` 50 | SrcColor, 51 | /// `(1 - src) * color` 52 | SrcColorComplement, 53 | /// `dst * color` 54 | DestColor, 55 | /// `(1 - dst) * color` 56 | DestColorComplement, 57 | /// `srcA * color` 58 | SrcAlpha, 59 | /// `(1 - src) * color` 60 | SrcAlphaComplement, 61 | /// `dstA * color` 62 | DstAlpha, 63 | /// `(1 - dstA) * color` 64 | DstAlphaComplement, 65 | /// For colors, `min(srcA, 1 - dstA)`, for alpha, `1` 66 | SrcAlphaSaturate, 67 | } 68 | 69 | /// Basic blending configuration. 70 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 71 | pub struct Blending { 72 | /// Blending equation to use. 73 | pub equation: Equation, 74 | /// Source factor. 75 | pub src: Factor, 76 | /// Destination factor. 77 | pub dst: Factor, 78 | } 79 | 80 | /// Blending configuration to represent combined or separate options. 81 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 82 | pub enum BlendingMode { 83 | /// Blending is disabled. 84 | Off, 85 | 86 | /// Blending with combined RGBA. 87 | Combined(Blending), 88 | 89 | /// Blending with RGB and alpha separately. 90 | Separate { 91 | /// Blending configuration for RGB components. 92 | rgb: Blending, 93 | /// Blending configuration for alpha component. 94 | alpha: Blending, 95 | }, 96 | } 97 | 98 | impl From for BlendingMode { 99 | fn from(blending: Blending) -> Self { 100 | BlendingMode::Combined(blending) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /luminance/src/depth_stencil.rs: -------------------------------------------------------------------------------- 1 | //! Depth test related features. 2 | 3 | /// Comparison to perform for depth / stencil operations. `a` is the incoming fragment’s data and b is the fragment’s 4 | /// data that is already stored. 5 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 6 | pub enum Comparison { 7 | /// Test never succeeds. 8 | Never, 9 | /// Test always succeeds. 10 | Always, 11 | /// Test succeeds if `a == b`. 12 | Equal, 13 | /// Test succeeds if `a != b`. 14 | NotEqual, 15 | /// Test succeeds if `a < b`. 16 | Less, 17 | /// Test succeeds if `a <= b`. 18 | LessOrEqual, 19 | /// Test succeeds if `a > b`. 20 | Greater, 21 | /// Test succeeds if `a >= b`. 22 | GreaterOrEqual, 23 | } 24 | 25 | /// Depth test, either enabled with a [`Comparison`] function, or disabled. 26 | /// 27 | /// If you disable depth test, fragments will always be blended, whatever the order in which they are written. 28 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 29 | pub enum DepthTest { 30 | /// Depth test is disabled. 31 | Off, 32 | 33 | /// Depth test is enabled and depth data will be compared with the carried [`Comparison`] value. 34 | On(Comparison), 35 | } 36 | 37 | /// Depth write mode. 38 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 39 | pub enum DepthWrite { 40 | /// Will write depth data. 41 | On, 42 | 43 | /// Will not write depth data. 44 | Off, 45 | } 46 | 47 | /// Stencil test, either enabled with a [`Comparison`] function and reference / mask values, and operations, or 48 | /// disabled. 49 | /// 50 | /// If you disable depth test, fragments will always be blended, whatever the order in which they are written. 51 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 52 | pub enum StencilTest { 53 | /// Stencil test is disabled. 54 | Off, 55 | 56 | /// Stencil test is enabled 57 | On { 58 | /// Comparison to apply to make a fragment pass the test. 59 | comparison: Comparison, 60 | 61 | /// Reference value for the comparison. 62 | reference: u8, 63 | 64 | /// The mask to apply on the fragment stencil value. 65 | mask: u8, 66 | 67 | /// Action to take when the depth test passes but not the stencil test. 68 | depth_passes_stencil_fails: StencilOp, 69 | 70 | /// Action to take when the stencil test passes but not the depth test. 71 | depth_fails_stencil_passes: StencilOp, 72 | 73 | /// Action to take when both the depth and stencil tests pass. 74 | depth_stencil_pass: StencilOp, 75 | }, 76 | } 77 | 78 | /// Possible stencil operations. 79 | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] 80 | pub enum StencilOp { 81 | /// Keep the current value. 82 | Keep, 83 | 84 | /// Set the stencil value to zero. 85 | Zero, 86 | 87 | /// Replace the stencil value. 88 | Replace, 89 | 90 | /// Increment the stencil value. 91 | /// 92 | /// If the stencil value reaches the maximum possible value, it is clamped. 93 | Increment, 94 | 95 | /// Increment the stencil value. 96 | /// 97 | /// If the stencil value reaches the maximum possible value, it wraps around back to `0`. 98 | IncrementWrap, 99 | 100 | /// Decrement the stencil value. 101 | /// 102 | /// If the stencil value reaches 0, it is clamped. 103 | Decrement, 104 | 105 | /// Decrement the stencil value. 106 | /// 107 | /// If the stencil value reaches 0, it wraps back to the maximum value. 108 | DecrementWrap, 109 | 110 | /// Bit-wise inversion. 111 | Invert, 112 | } 113 | -------------------------------------------------------------------------------- /luminance/src/face_culling.rs: -------------------------------------------------------------------------------- 1 | //! Face culling is the operation of removing triangles if they’re facing the screen in a specific 2 | //! direction with a specific mode. 3 | 4 | /// Face culling setup. 5 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 6 | pub enum FaceCulling { 7 | Off, 8 | 9 | On { 10 | /// Face culling order. 11 | order: FaceCullingOrder, 12 | /// Face culling mode. 13 | face: FaceCullingFace, 14 | }, 15 | } 16 | 17 | /// Default implementation of [`FaceCulling`]. 18 | /// 19 | /// - Order is [`FaceCullingOrder::CCW`]. 20 | /// - Face is [`FaceCullingFace::Back`]. 21 | impl Default for FaceCulling { 22 | fn default() -> Self { 23 | FaceCulling::On { 24 | order: FaceCullingOrder::CCW, 25 | face: FaceCullingFace::Back, 26 | } 27 | } 28 | } 29 | 30 | /// Face culling order. 31 | /// 32 | /// The order determines how a triangle is determined to be discarded. If the triangle’s vertices 33 | /// wind up in the same direction as the `FaceCullingOrder`, it’s assigned the front side, 34 | /// otherwise, it’s the back side. 35 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 36 | pub enum FaceCullingOrder { 37 | /// Clockwise order. 38 | CW, 39 | /// Counter-clockwise order. 40 | CCW, 41 | } 42 | 43 | /// Side to show and side to cull. 44 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 45 | pub enum FaceCullingFace { 46 | /// Cull the front side only. 47 | Front, 48 | /// Cull the back side only. 49 | Back, 50 | /// Always cull any triangle. 51 | Both, 52 | } 53 | -------------------------------------------------------------------------------- /luminance/src/framebuffer.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | 3 | use crate::{ 4 | dim::Dimensionable, 5 | render_slots::{CompatibleRenderSlots, DepthRenderSlot, RenderSlots}, 6 | }; 7 | 8 | pub struct Framebuffer 9 | where 10 | D: Dimensionable, 11 | RS: RenderSlots, 12 | DS: DepthRenderSlot, 13 | { 14 | handle: usize, 15 | size: D::Size, 16 | layers: RS::RenderLayers, 17 | depth_layer: DS::DepthRenderLayer, 18 | dropper: Box, 19 | } 20 | 21 | impl Framebuffer 22 | where 23 | D: Dimensionable, 24 | RS: RenderSlots, 25 | DS: DepthRenderSlot, 26 | { 27 | pub unsafe fn new( 28 | handle: usize, 29 | size: D::Size, 30 | layers: RS::RenderLayers, 31 | depth_layer: DS::DepthRenderLayer, 32 | dropper: Box, 33 | ) -> Self { 34 | Self { 35 | handle, 36 | size, 37 | layers, 38 | depth_layer, 39 | dropper, 40 | } 41 | } 42 | 43 | pub fn handle(&self) -> usize { 44 | self.handle 45 | } 46 | 47 | pub fn size(&self) -> &D::Size { 48 | &self.size 49 | } 50 | 51 | pub fn layers(&self) -> &RS::RenderLayers { 52 | &self.layers 53 | } 54 | 55 | pub fn depth_layer(&self) -> &DS::DepthRenderLayer { 56 | &self.depth_layer 57 | } 58 | } 59 | 60 | impl Drop for Framebuffer 61 | where 62 | D: Dimensionable, 63 | RS: RenderSlots, 64 | DS: DepthRenderSlot, 65 | { 66 | fn drop(&mut self) { 67 | (self.dropper)(self.handle); 68 | } 69 | } 70 | 71 | pub struct Back { 72 | _phantom: PhantomData<*const S>, 73 | } 74 | 75 | impl CompatibleRenderSlots for Back {} 76 | -------------------------------------------------------------------------------- /luminance/src/has_field.rs: -------------------------------------------------------------------------------- 1 | pub trait HasField { 2 | type FieldType; 3 | } 4 | -------------------------------------------------------------------------------- /luminance/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc( 2 | html_logo_url = "https://raw.githubusercontent.com/phaazon/luminance-rs/master/docs/imgs/luminance_alt.svg" 3 | )] 4 | #![allow(incomplete_features)] 5 | #![feature(adt_const_params)] 6 | 7 | #[cfg(feature = "luminance-derive")] 8 | pub use luminance_derive::*; 9 | 10 | pub mod backend; 11 | pub mod blending; 12 | pub mod context; 13 | pub mod depth_stencil; 14 | pub mod dim; 15 | pub mod face_culling; 16 | pub mod framebuffer; 17 | pub mod has_field; 18 | pub mod named_index; 19 | pub mod pipeline; 20 | pub mod pixel; 21 | pub mod primitive; 22 | pub mod render_slots; 23 | pub mod render_state; 24 | pub mod scissor; 25 | pub mod shader; 26 | pub mod texture; 27 | pub mod vertex; 28 | pub mod vertex_entity; 29 | pub mod vertex_storage; 30 | -------------------------------------------------------------------------------- /luminance/src/named_index.rs: -------------------------------------------------------------------------------- 1 | /// Map string names to indexes. 2 | pub trait NamedIndex { 3 | /// Unique index for `NAME`. 4 | const INDEX: usize; 5 | } 6 | 7 | #[macro_export] 8 | macro_rules! namespace { 9 | ($namespace:ident = { $first:literal }) => { 10 | #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 11 | pub struct $namespace; 12 | 13 | impl $crate::named_index::NamedIndex<$first> for $namespace { 14 | const INDEX: usize = 0; 15 | } 16 | }; 17 | 18 | ($namespace:ident = { $first:literal, $($rest:tt)* }) => { 19 | #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 20 | pub struct $namespace; 21 | 22 | impl $crate::named_index::NamedIndex<$first> for $namespace { 23 | const INDEX: usize = 0; 24 | } 25 | 26 | namespace!($namespace 1, $($rest)*); 27 | }; 28 | 29 | ($namespace:ident $index:expr, $name:literal) => { 30 | impl $crate::named_index::NamedIndex<$name> for $namespace { 31 | const INDEX: usize = $index; 32 | } 33 | }; 34 | 35 | ($namespace:ident $index:expr, $name:literal, $($rest:tt)*) => { 36 | impl $crate::named_index::NamedIndex<$name> for $namespace { 37 | const INDEX: usize = $index; 38 | } 39 | 40 | namespace!($namespace ($index + 1), $($rest)*); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /luminance/src/primitive.rs: -------------------------------------------------------------------------------- 1 | pub trait Primitive { 2 | const CONNECTOR: Connector; 3 | } 4 | 5 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 6 | pub enum Connector { 7 | Point, 8 | Line, 9 | LineStrip, 10 | Triangle, 11 | TriangleStrip, 12 | TriangleFan, 13 | Patch(usize), 14 | } 15 | 16 | macro_rules! impl_Primitive { 17 | ($t:ident) => { 18 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 19 | pub struct $t; 20 | 21 | impl Primitive for $t { 22 | const CONNECTOR: Connector = Connector::$t; 23 | } 24 | }; 25 | } 26 | 27 | impl_Primitive!(Point); 28 | impl_Primitive!(Line); 29 | impl_Primitive!(LineStrip); 30 | impl_Primitive!(Triangle); 31 | impl_Primitive!(TriangleStrip); 32 | impl_Primitive!(TriangleFan); 33 | 34 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] 35 | pub struct Patch; 36 | 37 | impl Primitive for Patch { 38 | const CONNECTOR: Connector = Connector::Patch(SIZE); 39 | } 40 | -------------------------------------------------------------------------------- /luminance/src/query.rs: -------------------------------------------------------------------------------- 1 | //! GPU queries. 2 | //! 3 | //! GPU queries allow to get information about the backend and the GPU in a straight-forward way. 4 | 5 | use crate::{ 6 | backend::query::{Query as QueryBackend, QueryError}, 7 | context::GraphicsContext, 8 | }; 9 | 10 | /// Query object. 11 | /// 12 | /// Such an object allows to query various parts of the backend and GPU. 13 | #[derive(Debug)] 14 | pub struct Query<'a, B> 15 | where 16 | B: ?Sized, 17 | { 18 | backend: &'a B, 19 | } 20 | 21 | impl<'a, B> Query<'a, B> 22 | where 23 | B: ?Sized + QueryBackend, 24 | { 25 | /// Create a new [`Query`] for a given context. 26 | pub fn new(ctxt: &'a mut impl GraphicsContext) -> Self { 27 | let backend = ctxt.backend(); 28 | Self { backend } 29 | } 30 | 31 | /// The implementation author, most of the time referred to as “vendor” or “compagny” responsible for the driver the 32 | /// implementation uses. 33 | pub fn backend_author(&self) -> Result { 34 | self.backend.backend_author() 35 | } 36 | 37 | /// The backend name. 38 | pub fn backend_name(&self) -> Result { 39 | self.backend.backend_name() 40 | } 41 | 42 | /// The backend version. 43 | pub fn backend_version(&self) -> Result { 44 | self.backend.backend_version() 45 | } 46 | 47 | /// The shading language version. 48 | pub fn backend_shading_lang_version(&self) -> Result { 49 | self.backend.backend_shading_lang_version() 50 | } 51 | 52 | /// Maximum number of elements a texture array can hold. 53 | pub fn max_texture_array_elements(&self) -> Result { 54 | self.backend.max_texture_array_elements() 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /luminance/src/render_state.rs: -------------------------------------------------------------------------------- 1 | //! GPU render state. 2 | //! 3 | //! Such a state controls how the GPU must operate some fixed pipeline functionality, such as the 4 | //! blending, depth test or face culling operations. 5 | 6 | use crate::{ 7 | blending::{Blending, BlendingMode, Equation, Factor}, 8 | depth_stencil::{Comparison, DepthTest, DepthWrite, StencilTest}, 9 | face_culling::FaceCulling, 10 | scissor::Scissor, 11 | }; 12 | 13 | /// GPU render state. 14 | /// 15 | /// You can get a default value with `RenderState::default` and set the operations you want with the 16 | /// various `RenderState::set_*` methods. 17 | #[derive(Clone, Debug, Eq, PartialEq)] 18 | pub struct RenderState { 19 | /// Blending configuration. 20 | pub blending: BlendingMode, 21 | 22 | /// Depth test configuration. 23 | pub depth_test: DepthTest, 24 | 25 | /// Depth write configuration. 26 | pub depth_write: DepthWrite, 27 | 28 | /// Stencil test configuration. 29 | pub stencil_test: StencilTest, 30 | 31 | /// Face culling configuration. 32 | pub face_culling: FaceCulling, 33 | 34 | /// Scissor region configuration. 35 | pub scissor: Scissor, 36 | } 37 | 38 | impl RenderState { 39 | pub fn set_blending(mut self, blending: BlendingMode) -> Self { 40 | self.blending = blending; 41 | self 42 | } 43 | 44 | pub fn set_depth_test(mut self, depth_test: DepthTest) -> Self { 45 | self.depth_test = depth_test; 46 | self 47 | } 48 | 49 | pub fn set_depth_write(mut self, depth_write: DepthWrite) -> Self { 50 | self.depth_write = depth_write; 51 | self 52 | } 53 | 54 | pub fn set_stencil_test(mut self, stencil_test: StencilTest) -> Self { 55 | self.stencil_test = stencil_test; 56 | self 57 | } 58 | 59 | pub fn set_face_culling(mut self, face_culling: FaceCulling) -> Self { 60 | self.face_culling = face_culling; 61 | self 62 | } 63 | 64 | pub fn set_scissor(mut self, scissor: Scissor) -> Self { 65 | self.scissor = scissor; 66 | self 67 | } 68 | } 69 | 70 | impl Default for RenderState { 71 | /// The default `RenderState`. 72 | /// 73 | /// - `blending`: `BlendingMode::Combined(Blending { equation: Equation::Additive, src: Factor::One, dst: Factor::Zero })` 74 | /// - `depth_test`: `DepthTest::On(Comparison::Less)` 75 | /// - `depth_write`: `DepthWrite::On` 76 | /// - `stencil_test`: `StencilTest::Off` 77 | /// - `face_culling`: `FaceCulling::default()` 78 | /// - 'scissor`: `Scissor::Off` 79 | fn default() -> Self { 80 | RenderState { 81 | blending: BlendingMode::Combined(Blending { 82 | equation: Equation::Additive, 83 | src: Factor::One, 84 | dst: Factor::Zero, 85 | }), 86 | depth_test: DepthTest::On(Comparison::Less), 87 | depth_write: DepthWrite::On, 88 | stencil_test: StencilTest::Off, 89 | face_culling: FaceCulling::default(), 90 | scissor: Scissor::Off, 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /luminance/src/scissor.rs: -------------------------------------------------------------------------------- 1 | //! Scissor test and related types. 2 | //! 3 | //! The scissor test is a special test performed at rendering time. It allows to define a region of the screen for which 4 | //! fragments will be discarded. 5 | 6 | /// The region outside of which fragments will be discarded. 7 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 8 | pub enum Scissor { 9 | Off, 10 | 11 | On { 12 | /// The x screen position of the scissor region. 13 | x: u32, 14 | 15 | /// The y screen position of the scissor region. 16 | y: u32, 17 | 18 | /// The screen width of the scissor region. 19 | width: u32, 20 | 21 | /// The screen height of the scissor region. 22 | height: u32, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /luminance/src/texture.rs: -------------------------------------------------------------------------------- 1 | use crate::{depth_stencil::Comparison, dim::Dimensionable}; 2 | use std::marker::PhantomData; 3 | 4 | /// How to wrap texture coordinates while sampling textures? 5 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 6 | pub enum Wrap { 7 | /// If textures coordinates lay outside of `[0;1]`, they will be clamped to either `0` or `1` for 8 | /// every components. 9 | ClampToEdge, 10 | /// Textures coordinates are repeated if they lay outside of `[0;1]`. Picture this as: 11 | /// 12 | /// ```ignore 13 | /// // given the frac function returning the fractional part of a floating number: 14 | /// coord_ith = frac(coord_ith); // always between `[0;1]` 15 | /// ``` 16 | Repeat, 17 | /// Same as `Repeat` but it will alternatively repeat between `[0;1]` and `[1;0]`. 18 | MirroredRepeat, 19 | } 20 | 21 | /// Minification filter. 22 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 23 | pub enum MinFilter { 24 | /// Nearest interpolation. 25 | Nearest, 26 | /// Linear interpolation between surrounding pixels. 27 | Linear, 28 | /// This filter will select the nearest mipmap between two samples and will perform a nearest 29 | /// interpolation afterwards. 30 | NearestMipmapNearest, 31 | /// This filter will select the nearest mipmap between two samples and will perform a linear 32 | /// interpolation afterwards. 33 | NearestMipmapLinear, 34 | /// This filter will linearly interpolate between two mipmaps, which selected texels would have 35 | /// been interpolated with a nearest filter. 36 | LinearMipmapNearest, 37 | /// This filter will linearly interpolate between two mipmaps, which selected texels would have 38 | /// been linarily interpolated as well. 39 | LinearMipmapLinear, 40 | } 41 | 42 | /// Magnification filter. 43 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 44 | pub enum MagFilter { 45 | /// Nearest interpolation. 46 | Nearest, 47 | /// Linear interpolation between surrounding pixels. 48 | Linear, 49 | } 50 | 51 | /// A [`Sampler`] object gives hint on how a [`Texture`] should be sampled. 52 | #[derive(Clone, Copy, Debug)] 53 | pub struct TextureSampling { 54 | /// How should we wrap around the *r* sampling coordinate? 55 | pub wrap_r: Wrap, 56 | 57 | /// How should we wrap around the *s* sampling coordinate? 58 | pub wrap_s: Wrap, 59 | 60 | /// How should we wrap around the *t* sampling coordinate? 61 | pub wrap_t: Wrap, 62 | 63 | /// Minification filter. 64 | pub min_filter: MinFilter, 65 | 66 | /// Magnification filter. 67 | pub mag_filter: MagFilter, 68 | 69 | /// For depth textures, should we perform depth comparison and if so, how? 70 | pub depth_comparison: Option, 71 | } 72 | 73 | impl Default for TextureSampling { 74 | fn default() -> Self { 75 | TextureSampling { 76 | wrap_r: Wrap::ClampToEdge, 77 | wrap_s: Wrap::ClampToEdge, 78 | wrap_t: Wrap::ClampToEdge, 79 | min_filter: MinFilter::Linear, 80 | mag_filter: MagFilter::Linear, 81 | depth_comparison: None, 82 | } 83 | } 84 | } 85 | 86 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 87 | pub enum Mipmaps { 88 | No, 89 | Yes { count: usize }, 90 | } 91 | 92 | impl Mipmaps { 93 | pub fn count(count: usize) -> Self { 94 | Mipmaps::Yes { count } 95 | } 96 | } 97 | 98 | pub struct Texture 99 | where 100 | D: Dimensionable, 101 | { 102 | handle: usize, 103 | dropper: Box, 104 | size: D::Size, 105 | _phantom: PhantomData<*const P>, 106 | } 107 | 108 | impl Texture 109 | where 110 | D: Dimensionable, 111 | { 112 | pub unsafe fn new(handle: usize, dropper: Box, size: D::Size) -> Self { 113 | Self { 114 | handle, 115 | dropper, 116 | size, 117 | _phantom: PhantomData, 118 | } 119 | } 120 | 121 | pub fn handle(&self) -> usize { 122 | self.handle 123 | } 124 | 125 | pub fn size(&self) -> D::Size { 126 | self.size 127 | } 128 | } 129 | 130 | impl Drop for Texture 131 | where 132 | D: Dimensionable, 133 | { 134 | fn drop(&mut self) { 135 | (self.dropper)(self.handle) 136 | } 137 | } 138 | 139 | pub struct InUseTexture { 140 | handle: usize, 141 | dropper: Box, 142 | _phantom: PhantomData<*const (D, S)>, 143 | } 144 | 145 | impl InUseTexture { 146 | pub unsafe fn new(handle: usize, dropper: Box) -> Self { 147 | Self { 148 | handle, 149 | dropper, 150 | _phantom: PhantomData, 151 | } 152 | } 153 | 154 | pub fn handle(&self) -> usize { 155 | self.handle 156 | } 157 | } 158 | 159 | impl Drop for InUseTexture { 160 | fn drop(&mut self) { 161 | (self.dropper)(self.handle) 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /luminance/src/vertex_storage.rs: -------------------------------------------------------------------------------- 1 | //! Vertex storage containers. 2 | 3 | use crate::{ 4 | has_field::HasField, 5 | vertex::{Deinterleave, Vertex}, 6 | }; 7 | use std::{marker::PhantomData, mem}; 8 | 9 | #[derive(Debug)] 10 | pub enum VertexStorage<'a, V> { 11 | NoStorage, 12 | Interleaved(&'a mut Interleaved), 13 | Deinterleaved(&'a mut Deinterleaved), 14 | } 15 | 16 | pub trait AsVertexStorage { 17 | fn as_vertex_storage(&mut self) -> VertexStorage; 18 | } 19 | 20 | impl AsVertexStorage for () { 21 | fn as_vertex_storage(&mut self) -> VertexStorage { 22 | VertexStorage::NoStorage 23 | } 24 | } 25 | 26 | impl AsVertexStorage for Interleaved { 27 | fn as_vertex_storage(&mut self) -> VertexStorage { 28 | VertexStorage::Interleaved(self) 29 | } 30 | } 31 | 32 | impl AsVertexStorage for Deinterleaved { 33 | fn as_vertex_storage(&mut self) -> VertexStorage { 34 | VertexStorage::Deinterleaved(self) 35 | } 36 | } 37 | 38 | pub trait VertexStorageFamily { 39 | type Storage: AsVertexStorage; 40 | } 41 | 42 | impl VertexStorageFamily for () { 43 | type Storage = (); 44 | } 45 | 46 | #[derive(Debug)] 47 | pub struct Interleaving; 48 | 49 | impl VertexStorageFamily for Interleaving { 50 | type Storage = Interleaved; 51 | } 52 | 53 | #[derive(Debug)] 54 | pub struct Deinterleaving; 55 | 56 | impl VertexStorageFamily for Deinterleaving { 57 | type Storage = Deinterleaved; 58 | } 59 | 60 | /// Store vertices as an interleaved array. 61 | #[derive(Debug)] 62 | pub struct Interleaved { 63 | vertices: Vec, 64 | primitive_restart: bool, 65 | } 66 | 67 | impl Interleaved { 68 | /// Build a new interleaved storage. 69 | pub fn new() -> Self { 70 | Self { 71 | vertices: Vec::new(), 72 | primitive_restart: false, 73 | } 74 | } 75 | 76 | /// Set vertices. 77 | pub fn set_vertices(mut self, vertices: impl Into>) -> Self { 78 | self.vertices = vertices.into(); 79 | self 80 | } 81 | 82 | /// Get access to the vertices. 83 | pub fn vertices(&self) -> &Vec { 84 | &self.vertices 85 | } 86 | 87 | /// Get access to the vertices. 88 | pub fn vertices_mut(&mut self) -> &mut Vec { 89 | &mut self.vertices 90 | } 91 | 92 | /// Get access to the vertices as bytes. 93 | pub fn vertices_as_bytes(&self) -> &[u8] { 94 | let data = self.vertices.as_ptr(); 95 | let len = self.vertices.len(); 96 | 97 | unsafe { std::slice::from_raw_parts(data as _, len * mem::size_of::()) } 98 | } 99 | 100 | pub fn primitive_restart(&self) -> bool { 101 | self.primitive_restart 102 | } 103 | 104 | pub fn set_primitive_restart(mut self, primitive_restart: bool) -> Self { 105 | self.primitive_restart = primitive_restart; 106 | self 107 | } 108 | } 109 | 110 | /// Store vertices as deinterleaved arrays. 111 | #[derive(Debug)] 112 | pub struct Deinterleaved { 113 | components_list: Vec>, 114 | primitive_restart: bool, 115 | _phantom: PhantomData, 116 | } 117 | 118 | impl Deinterleaved 119 | where 120 | V: Vertex, 121 | { 122 | /// Create a new empty deinterleaved storage. 123 | pub fn new() -> Self { 124 | let components_count = V::components_count(); 125 | 126 | Self { 127 | components_list: vec![Vec::new(); components_count], 128 | primitive_restart: false, 129 | _phantom: PhantomData, 130 | } 131 | } 132 | 133 | /// Set named components. 134 | pub fn set_components( 135 | mut self, 136 | components: impl Into>::FieldType>>, 137 | ) -> Self 138 | where 139 | V: Deinterleave, 140 | { 141 | // turn the components into a raw vector (Vec) 142 | let boxed_slice = components.into().into_boxed_slice(); 143 | let len = boxed_slice.len(); 144 | let len_bytes = len * std::mem::size_of::<>::FieldType>(); 145 | let ptr = Box::into_raw(boxed_slice); 146 | let raw = unsafe { Vec::from_raw_parts(ptr as _, len_bytes, len_bytes) }; 147 | 148 | self.components_list[>::RANK] = raw; 149 | self 150 | } 151 | 152 | /// Get all components 153 | pub fn components_list(&self) -> &Vec> { 154 | &self.components_list 155 | } 156 | 157 | pub fn primitive_restart(&self) -> bool { 158 | self.primitive_restart 159 | } 160 | 161 | pub fn set_primitive_restart(mut self, primitive_restart: bool) -> Self { 162 | self.primitive_restart = primitive_restart; 163 | self 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /luminance/tests/derive_memory_layout.rs: -------------------------------------------------------------------------------- 1 | #![cfg(all(feature = "luminance-derive", feature = "mint"))] 2 | #![allow(incomplete_features)] 3 | #![feature(const_cmp)] 4 | 5 | use luminance::{Std140, Std430}; 6 | use std::mem::size_of; 7 | 8 | #[test] 9 | fn std140() { 10 | #[derive(Debug, Std140)] 11 | struct X { 12 | pub x: f32, 13 | } 14 | 15 | let x = XStd140::from(X { x: 1. }); 16 | assert_eq!(x._pad_x.len(), 0); 17 | assert_eq!(x._pad_struct.len(), 12); 18 | 19 | assert_eq!(size_of::(), 16); 20 | 21 | #[derive(Debug, Std140)] 22 | struct XYZ { 23 | pub xyz: mint::Vector3, 24 | } 25 | 26 | let xyz = XYZStd140::from(XYZ { 27 | xyz: mint::Vector3 { 28 | x: 1., 29 | y: 2., 30 | z: 3., 31 | }, 32 | }); 33 | assert_eq!(xyz._pad_xyz.len(), 0); 34 | assert_eq!(xyz._pad_struct.len(), 4); 35 | 36 | assert_eq!(size_of::(), 16); 37 | 38 | #[derive(Debug, Std140)] 39 | struct XYZW { 40 | xyz: mint::Vector3, 41 | w: f32, 42 | } 43 | 44 | let xyzw = XYZWStd140::from(XYZW { 45 | xyz: mint::Vector3 { 46 | x: 1., 47 | y: 2., 48 | z: 3., 49 | }, 50 | w: 4., 51 | }); 52 | assert_eq!(xyzw._pad_xyz.len(), 0); 53 | assert_eq!(xyzw._pad_w.len(), 0); 54 | assert_eq!(xyzw._pad_struct.len(), 0); 55 | 56 | assert_eq!(size_of::(), 16); 57 | 58 | #[derive(Debug, Std140)] 59 | struct XYZWSwapped { 60 | w: f32, 61 | xyz: mint::Vector3, 62 | } 63 | 64 | let xyzw_swapped = XYZWSwappedStd140::from(XYZWSwapped { 65 | w: 1., 66 | xyz: mint::Vector3 { 67 | x: 2., 68 | y: 3., 69 | z: 4., 70 | }, 71 | }); 72 | assert_eq!(xyzw_swapped._pad_w.len(), 0); 73 | assert_eq!(xyzw_swapped._pad_xyz.len(), 12); 74 | assert_eq!(xyzw_swapped._pad_struct.len(), 4); 75 | 76 | assert_eq!(size_of::(), 32); 77 | } 78 | 79 | #[test] 80 | fn std430() { 81 | #[derive(Debug, Std430)] 82 | struct X { 83 | pub x: f32, 84 | } 85 | 86 | let x = XStd430::from(X { x: 1. }); 87 | assert_eq!(x._pad_x.len(), 0); 88 | assert_eq!(x._pad_struct.len(), 0); 89 | 90 | assert_eq!(size_of::(), 4); 91 | 92 | #[derive(Debug, Std430)] 93 | struct XYZ { 94 | pub xyz: mint::Vector3, 95 | } 96 | 97 | let xyz = XYZStd430::from(XYZ { 98 | xyz: mint::Vector3 { 99 | x: 1., 100 | y: 2., 101 | z: 3., 102 | }, 103 | }); 104 | assert_eq!(xyz._pad_xyz.len(), 0); 105 | assert_eq!(xyz._pad_struct.len(), 4); 106 | 107 | assert_eq!(size_of::(), 16); 108 | 109 | #[derive(Debug, Std430)] 110 | struct XYZW { 111 | xyz: mint::Vector3, 112 | w: f32, 113 | } 114 | 115 | let xyzw = XYZWStd430::from(XYZW { 116 | xyz: mint::Vector3 { 117 | x: 1., 118 | y: 2., 119 | z: 3., 120 | }, 121 | w: 4., 122 | }); 123 | assert_eq!(xyzw._pad_xyz.len(), 0); 124 | assert_eq!(xyzw._pad_w.len(), 0); 125 | assert_eq!(xyzw._pad_struct.len(), 0); 126 | 127 | assert_eq!(size_of::(), 16); 128 | 129 | #[derive(Debug, Std430)] 130 | struct XYZWSwapped { 131 | w: f32, 132 | xyz: mint::Vector3, 133 | } 134 | 135 | let xyzw_swapped = XYZWSwappedStd430::from(XYZWSwapped { 136 | w: 1., 137 | xyz: mint::Vector3 { 138 | x: 2., 139 | y: 3., 140 | z: 4., 141 | }, 142 | }); 143 | assert_eq!(xyzw_swapped._pad_w.len(), 0); 144 | assert_eq!(xyzw_swapped._pad_xyz.len(), 12); 145 | assert_eq!(xyzw_swapped._pad_struct.len(), 4); 146 | 147 | assert_eq!(size_of::(), 32); 148 | } 149 | -------------------------------------------------------------------------------- /luminance/tests/derive_render_slots.rs: -------------------------------------------------------------------------------- 1 | #![cfg(all(feature = "luminance-derive", feature = "mint"))] 2 | #![allow(incomplete_features)] 3 | #![feature(adt_const_params)] 4 | 5 | use luminance::{ 6 | has_field::HasField, 7 | pixel::{Pixel, R32F, RGB32F}, 8 | render_slots::RenderChannelDesc, 9 | render_slots::{CompatibleRenderSlots, RenderSlots}, 10 | RenderSlots, 11 | }; 12 | 13 | #[derive(RenderSlots)] 14 | struct Slots { 15 | _diffuse: RGB32F, 16 | _normal: RGB32F, 17 | _test: R32F, 18 | } 19 | 20 | #[derive(RenderSlots)] 21 | struct Slots1 { 22 | _diffuse: RGB32F, 23 | } 24 | 25 | #[test] 26 | fn compatible_render_slots() { 27 | fn has_field() 28 | where 29 | S: RenderSlots + HasField, 30 | { 31 | } 32 | 33 | fn compatible() 34 | where 35 | S1: CompatibleRenderSlots, 36 | { 37 | } 38 | 39 | has_field::<"_diffuse", RGB32F, Slots>(); 40 | has_field::<"_normal", RGB32F, Slots>(); 41 | has_field::<"_test", R32F, Slots>(); 42 | 43 | has_field::<"_diffuse", RGB32F, Slots1>(); 44 | 45 | compatible::(); 46 | compatible::(); 47 | } 48 | 49 | #[test] 50 | fn render_slots() { 51 | let diffuse = RenderChannelDesc { 52 | name: "_diffuse", 53 | fmt: RGB32F::PIXEL_FMT, 54 | }; 55 | let normal = RenderChannelDesc { 56 | name: "_normal", 57 | fmt: RGB32F::PIXEL_FMT, 58 | }; 59 | let test = RenderChannelDesc { 60 | name: "_test", 61 | fmt: R32F::PIXEL_FMT, 62 | }; 63 | 64 | assert_eq!(Slots::color_channel_descs(), &[diffuse, normal, test]); 65 | } 66 | -------------------------------------------------------------------------------- /luminance/tests/uniform_interface.rs: -------------------------------------------------------------------------------- 1 | // #![cfg(feature = "derive")] 2 | // 3 | // use luminance::shader::Uniform; 4 | // use luminance::UniformInterface; 5 | // 6 | // #[test] 7 | // fn derive_uniform_interface() { 8 | // #[derive(UniformInterface)] 9 | // struct SimpleUniformInterface { 10 | // _t: Uniform, 11 | // } 12 | // } 13 | // 14 | // #[test] 15 | // fn derive_unbound_uniform_interface() { 16 | // #[derive(UniformInterface)] 17 | // struct SimpleUniformInterface { 18 | // #[uniform(unbound)] 19 | // _t: Uniform, 20 | // } 21 | // } 22 | // 23 | // #[test] 24 | // fn derive_renamed_uniform_interface() { 25 | // #[derive(UniformInterface)] 26 | // struct SimpleUniformInterface { 27 | // #[uniform(name = "time")] 28 | // _t: Uniform, 29 | // } 30 | // } 31 | // 32 | // #[test] 33 | // fn derive_unbound_renamed_uniform_interface() { 34 | // #[derive(UniformInterface)] 35 | // struct SimpleUniformInterface { 36 | // #[uniform(name = "time", unbound)] 37 | // _t: Uniform, 38 | // #[uniform(unbound, name = "time")] 39 | // _t2: Uniform, 40 | // } 41 | // } 42 | -------------------------------------------------------------------------------- /luminance/tests/vertex.rs: -------------------------------------------------------------------------------- 1 | #![allow(incomplete_features)] 2 | #![feature(adt_const_params)] 3 | 4 | use luminance::{ 5 | has_field::HasField, 6 | namespace, 7 | vertex::{CompatibleVertex, Vertex as _, VertexAttrib, VertexBufferDesc}, 8 | Vertex, 9 | }; 10 | 11 | namespace! { 12 | Namespace = { "pos", "nor", "col", "weight" } 13 | } 14 | 15 | #[repr(C)] 16 | #[derive(Clone, Copy, Debug, Vertex)] 17 | #[vertex(namespace = "Namespace")] 18 | struct Vertex { 19 | pos: [f32; 3], 20 | nor: [f32; 3], 21 | col: [u8; 4], 22 | } 23 | 24 | #[test] 25 | fn vertex_desc() { 26 | let expected_desc = vec![ 27 | VertexBufferDesc::new(0, "pos", <[f32; 3] as VertexAttrib>::VERTEX_ATTRIB_DESC), 28 | VertexBufferDesc::new(1, "nor", <[f32; 3] as VertexAttrib>::VERTEX_ATTRIB_DESC), 29 | VertexBufferDesc::new(2, "col", <[u8; 4] as VertexAttrib>::VERTEX_ATTRIB_DESC), 30 | ]; 31 | 32 | assert_eq!(Vertex::vertex_desc(), expected_desc); 33 | } 34 | 35 | #[test] 36 | fn has_field() { 37 | fn must_have_field() 38 | where 39 | V: HasField, 40 | { 41 | } 42 | 43 | must_have_field::<"pos", Vertex, [f32; 3]>(); 44 | must_have_field::<"nor", Vertex, [f32; 3]>(); 45 | must_have_field::<"col", Vertex, [u8; 4]>(); 46 | } 47 | 48 | #[test] 49 | fn compatible_vertex_types() { 50 | fn is_compatible() 51 | where 52 | V: CompatibleVertex, 53 | { 54 | } 55 | 56 | #[repr(C)] 57 | #[derive(Clone, Copy, Debug, Vertex)] 58 | #[vertex(namespace = "Namespace")] 59 | struct VertexSame { 60 | pos: [f32; 3], 61 | nor: [f32; 3], 62 | col: [u8; 4], 63 | } 64 | 65 | is_compatible::(); 66 | 67 | #[repr(C)] 68 | #[derive(Clone, Copy, Debug, Vertex)] 69 | #[vertex(namespace = "Namespace")] 70 | struct VertexInclude { 71 | pos: [f32; 3], 72 | nor: [f32; 3], 73 | col: [u8; 4], 74 | weight: f32, 75 | } 76 | 77 | is_compatible::(); 78 | } 79 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2018" 2 | 3 | fn_args_layout = "Tall" 4 | force_explicit_abi = true 5 | hard_tabs = false 6 | max_width = 100 7 | merge_derives = true 8 | newline_style = "Unix" 9 | remove_nested_parens = true 10 | reorder_imports = true 11 | reorder_modules = true 12 | tab_spaces = 2 13 | use_field_init_shorthand = true 14 | use_small_heuristics = "Default" 15 | use_try_shorthand = true 16 | -------------------------------------------------------------------------------- /scripts/rollout: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | # 3 | # This script is a great helper when having to perform roll out to crates.io. When the CI is all 4 | # green and that you need to release a crate, you can use this tool to publish crates to crates.io. 5 | # 6 | # You will need crates.io credentials to call this script; use `cargo login ` to get your 7 | # credentials. 8 | # 9 | # This script should be called from the root directory. 10 | 11 | # List of crates to roll out. Order matters. 12 | crates=( 13 | luminance-derive 14 | luminance 15 | luminance-std140 16 | luminance-gl 17 | luminance-glfw 18 | luminance-glutin 19 | luminance-sdl2 20 | luminance-webgl 21 | luminance-web-sys 22 | luminance-front 23 | ) 24 | 25 | function auto_publish_crate() { 26 | echo "Publishing $1 to creates.io…" 27 | 28 | ret=1 29 | try=1 30 | while [ $ret != 0 ] 31 | do 32 | echo " try $try" 33 | (cd $1 && cargo publish) 34 | ret=$? 35 | 36 | if [ $ret != 0 ] 37 | then 38 | try=$(($try + 1)) 39 | sleep 5 40 | else 41 | break 42 | fi 43 | done 44 | } 45 | 46 | function get_crate_version() { 47 | cargo read-manifest --manifest-path $1/Cargo.toml | jq -r ".version" | sed s/\.0$// 48 | } 49 | 50 | function auto_create_git_tag() { 51 | echo "Current tags for $1:" 52 | git tag | rg ^$1-\\d 53 | echo "Creating tag $1-$2?" 54 | (git tag $1-$2 && echo -e " created git tag $1-\e[034;3m$2\e[0;0m") 55 | } 56 | 57 | function auto_push_git_tags() { 58 | echo "Pushing tags" 59 | git push origin --tags 60 | } 61 | 62 | function rollout() { 63 | for crate in $*; do 64 | version=$(get_crate_version $crate) 65 | echo -e "\e[032;1mRolling out \e[039;0m$crate-\e[034;3m$version\e[0;0m" 66 | 67 | auto_publish_crate $crate 68 | auto_create_git_tag $crate $version 69 | done 70 | 71 | auto_push_git_tags 72 | } 73 | 74 | case "$*" in 75 | "auto") 76 | rollout ${crates[@]} 77 | ;; 78 | 79 | *) 80 | rollout $* 81 | ;; 82 | esac 83 | --------------------------------------------------------------------------------