pipeline/
pipeline.rs

1extern crate est_render;
2
3use est_render::prelude::*;
4
5pub(crate) const VERTEX_DRAWING_SHADER: &str = r#"
6// Vertex Shader
7struct VertexInput {
8    @location(0) position: vec3<f32>,
9    @location(1) color: vec4<f32>,
10    @location(2) texCoord: vec2<f32>,
11};
12
13struct VertexOutput {
14    @builtin(position) position: vec4<f32>,
15    @location(0) color: vec4<f32>,
16    @location(1) texCoord: vec2<f32>,
17};
18
19@vertex
20fn main_vertex(input: VertexInput) -> VertexOutput {
21    var output: VertexOutput;
22    output.position = vec4<f32>(input.position, 1.0);
23    output.color = input.color;
24    output.texCoord = input.texCoord;
25    return output;
26}"#;
27
28pub(crate) const FRAGMENT_DRAWING_SHADER: &str = r#"
29// Fragment Shader
30@group(0) @binding(0) var myTexture: texture_2d<f32>;
31@group(0) @binding(1) var mySampler: sampler;
32
33struct FragmentInput {
34    @location(0) color: vec4<f32>,
35    @location(1) texCoord: vec2<f32>,
36};
37
38@fragment
39fn main_fragment(input: FragmentInput) -> @location(0) vec4<f32> {
40    let checkerSize = 50.0;
41    let x = floor(input.texCoord.x * checkerSize);
42    let y = floor(input.texCoord.y * checkerSize);
43    let isWhite = ((x + y) % 2.0) == 0.0;
44
45    if isWhite {
46        return input.color; // white square
47    } else {
48        return vec4<f32>(0.0, 0.0, 0.0, 1.0); // black square
49    }
50}"#;
51
52pub(crate) const COMPUTE_NOOP_SHADER: &str = r#"
53// Compute Shader
54@compute @workgroup_size(1)
55fn main() {
56    // This compute shader does nothing
57    // It can be used to test the compute pipeline setup
58}
59"#;
60
61fn main() {
62    let mut runner = est_render::runner::new().expect("Failed to create runner");
63    let mut window = runner
64        .create_window("Engine Example", Point2::new(800, 600))
65        .build()
66        .expect("Failed to create window");
67
68    let mut gpu = est_render::gpu::new(Some(&mut window))
69        .build()
70        .expect("Failed to create GPU");
71
72    let mut msaa_texture = gpu
73        .create_texture()
74        .set_render_target(Point2::new(800, 600), None)
75        .set_sample_count(SampleCount::SampleCount4)
76        .build()
77        .expect("Failed to create MSAA texture");
78
79    let blank_texture = gpu
80        .create_texture()
81        .set_raw_image(
82            &[255u8; 4],
83            Point2::new(1, 1),
84            TextureFormat::Bgra8Unorm,
85        )
86        .set_usage(TextureUsage::Sampler)
87        .build()
88        .expect("Failed to create blank texture");
89
90    let shader = gpu
91        .create_graphics_shader()
92        .set_vertex_code(VERTEX_DRAWING_SHADER)
93        .set_fragment_code(FRAGMENT_DRAWING_SHADER)
94        .build()
95        .expect("Failed to create graphics shader");
96
97    let compute_shader = gpu
98        .create_compute_shader()
99        .set_source(COMPUTE_NOOP_SHADER)
100        .build()
101        .expect("Failed to create compute shader");
102
103    let pipeline = gpu
104        .create_render_pipeline()
105        .set_shader(Some(&shader))
106        .set_blend(Some(&BlendState::ALPHA_BLEND))
107        .set_attachment_texture(0, 0, Some(&blank_texture))
108        .set_attachment_sampler(0, 1, Some(&TextureSampler::DEFAULT))
109        .build()
110        .expect("Failed to create render pipeline");
111
112    let compute_pipeline = gpu
113        .create_compute_pipeline()
114        .set_shader(Some(&compute_shader))
115        .build()
116        .expect("Failed to create compute pipeline");
117
118    // Triangle vertices
119    let vertices = vec![
120        Vertex {
121            position: Vector3::new(-0.5, -0.5, 0.0),
122            color: Color::new(1.0, 0.0, 0.0, 1.0),
123            texcoord: Vector2::new(0.0, 1.0),
124        },
125        Vertex {
126            position: Vector3::new(0.5, -0.5, 0.0),
127            color: Color::new(0.0, 1.0, 0.0, 1.0),
128            texcoord: Vector2::new(1.0, 1.0),
129        },
130        Vertex {
131            position: Vector3::new(0.0, 0.5, 0.0),
132            color: Color::new(0.0, 0.0, 1.0, 1.0),
133            texcoord: Vector2::new(0.5, 0.0),
134        },
135    ];
136
137    let indexes = vec![0u16, 1u16, 2u16];
138
139    let vbo = gpu
140        .create_buffer()
141        .set_data_vec(vertices)
142        .set_usage(BufferUsage::VERTEX)
143        .build()
144        .expect("Failed to create vertex buffer");
145
146    let ibo = gpu
147        .create_buffer()
148        .set_data_vec(indexes)
149        .set_usage(BufferUsage::INDEX)
150        .build()
151        .expect("Failed to create index buffer");
152
153    while runner.pump_events(PumpMode::WaitDraw) {
154        for event in runner.get_events() {
155            match event {
156                Event::KeyboardInput {
157                    window_id,
158                    key,
159                    pressed,
160                } => {
161                    if *window_id == window.id() && key == "Escape" && *pressed {
162                        window.quit();
163                    }
164                }
165                Event::WindowResized { window_id: _, size } => {
166                    if size.x <= 0 || size.y <= 0 {
167                        continue; // Skip invalid sizes
168                    }
169
170                    msaa_texture = gpu
171                        .create_texture()
172                        .set_render_target(Point2::new(size.x as u32, size.y as u32), None)
173                        .set_sample_count(SampleCount::SampleCount4)
174                        .build()
175                        .expect("Failed to resize MSAA texture");
176                }
177                Event::RedrawRequested { window_id: _ } => {
178                    if let Ok(mut cmd) = gpu.begin_command() {
179                        if let Ok(mut cm) = cmd.begin_computepass() {
180                            cm.set_pipeline(Some(&compute_pipeline));
181                            cm.dispatch(1, 1, 1);
182                        }
183
184                        if let Ok(mut rp) = cmd.begin_renderpass() {
185                            rp.set_clear_color(Color::BLACK);
186                            rp.push_msaa_texture(&msaa_texture);
187
188                            rp.set_pipeline(Some(&pipeline));
189                            rp.set_gpu_buffer(Some(&vbo), Some(&ibo));
190                            rp.draw_indexed(0..3, 0, 1);
191                        }
192                    }
193
194                    window.request_redraw();
195                }
196                _ => {}
197            }
198        }
199    }
200}