euc/lib.rs
1//! [](https://crates.io/crates/euc)
2//! [](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}