1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
//! [![crates.io](https://img.shields.io/crates/v/euc.svg)](https://crates.io/crates/euc) //! [![crates.io](https://docs.rs/euc/badge.svg)](https://docs.rs/euc) //! //! <img src="misc/example.png" alt="Utah teapot, rendered with Euc" width="100%"/> //! //! # Example //! ```ignore //! struct Example; //! //! impl Pipeline for Example { //! type Vertex = [f32; 2]; //! type VsOut = (); //! type Pixel = [u8; 4]; //! //! // Vertex shader //! fn vert(&self, pos: &Self::Vertex) -> ([f32; 3], Self::VsOut) { //! ([pos[0], pos[1], 0.0], ()) //! } //! //! // Fragment shader //! fn frag(&self, _: &Self::VsOut) -> Self::Pixel { //! [255, 0, 0, 255] // Red //! } //! } //! //! fn main() { //! let mut color = Buffer2d::new([640, 480], [0; 4]); //! Example.draw::<Triangles<(f32,)>, _>( //! &[ //! [-1.0, -1.0], //! [ 1.0, -1.0], //! [ 0.0, 1.0], //! ], //! &mut color, //! None, //! ); //! } //! ``` #![no_std] #[macro_use] extern crate alloc; pub mod buffer; pub mod interpolate; pub mod rasterizer; // Reexports pub use self::interpolate::Interpolate; pub use self::rasterizer::{DepthStrategy, Rasterizer}; /// Represents the high-level structure of a rendering pipeline. /// /// Conventionally, uniform data is stores as state within the type itself. /// /// This governs the following things: /// /// - Vertex position and data calculation (computed by the vertex shader) /// - Determining whether each polygon is 'backfacing', and optionally skipping it /// - Rasterization (performed internally by `euc`) /// - Comparing the fragment depth against the depth buffer to determine whether it is occluded, /// and optionally skipping it /// - Fragment output calculation (computed by the fragment shader) /// /// In the future, `euc` may extend its capabilities to include compute, geometry, and tesselation /// shaders. pub trait Pipeline where Self: Sized, { /// The type of the vertex shader input data. /// /// This usually consists of the vertex's position, normal, colour, texture coordinates, and /// other such per-vertex information. When vertex indexing is used, this tends to consist of /// the vertex index. type Vertex; /// The type of the data that gets passed on from the vertex shader to the fragment shader. /// /// This usually consists of the fragment's normal, colour, texture coordinates and other such /// per-fragment information. type VsOut: Clone + Interpolate; /// The type of emitted pixels. /// /// This type is emitted by the fragment shader and usually corresponds to the colour of the /// pixel. type Pixel: Clone; /// The vertex shader fn vert(&self, vertex: &Self::Vertex) -> ([f32; 4], Self::VsOut); /// The fragment shader fn frag(&self, vs_out: &Self::VsOut) -> Self::Pixel; /// A method used to determine what depth buffer strategy should be used when determining /// fragment occlusion. /// /// This method will be called at minimum only once per draw call, but may be called an /// arbitrary number of times. #[inline(always)] fn get_depth_strategy(&self) -> DepthStrategy { DepthStrategy::IfLessWrite } /// Perform a draw call with the given uniform data, vertex array, output target and supplement /// type. /// /// The supplement type is commonly used to represent additional surfaces required by the /// rasterizer, such as a depth buffer target. fn draw<R: Rasterizer, T: Target<Item = Self::Pixel>>( &self, vertices: &[Self::Vertex], target: &mut T, supplement: <R as Rasterizer>::Supplement, ) { R::draw::<Self, T>(self, vertices, target, supplement) } } /// Represents a 2-dimensional rendering target that can have pixel data read and written to it. pub trait Target { /// The type of items contained within this target. type Item: Clone; /// Get the dimensions of the target. fn size(&self) -> [usize; 2]; /// Set the item at the specified location in the target to the given item. The validity of the /// location is not checked, and as such this method is marked `unsafe`. unsafe fn set(&mut self, pos: [usize; 2], item: Self::Item); /// Get a copy of the item at the specified location in the target. The validity of the /// location is not checked, and as such this method is marked `unsafe`. unsafe fn get(&self, pos: [usize; 2]) -> Self::Item; /// Clear the target with copies of the specified item. fn clear(&mut self, fill: Self::Item); } impl<T: Default + Clone> Target for (T,) { type Item = T; fn size(&self) -> [usize; 2] { [1; 2] } unsafe fn set(&mut self, pos: [usize; 2], item: Self::Item) {} unsafe fn get(&self, pos: [usize; 2]) -> Self::Item { Self::Item::default() } fn clear(&mut self, fill: Self::Item) {} }