euc/
lib.rs

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