1use crate::{
2 buffer::{index::Index, IndexBuffer, Vertex, VertexBuffer},
3 shader::Shader,
4};
5use std::{marker::PhantomData, ops::Range};
6use wgpu::{BindGroup, TextureFormat};
7
8pub struct RenderPass<'e, Sv = (), Bv = (), Si = (), Bi = (), const PIPELINE_BOUND: bool = false> {
11 pub(crate) inner: wgpu::RenderPass<'e>,
12 pub(crate) format: TextureFormat,
13
14 _p: PhantomData<(Sv, Bv, Si, Bi)>,
15}
16
17impl<'e, Sv, Bv, Si, Bi, const PIPELINE_BOUND: bool>
20 RenderPass<'e, Sv, Bv, Si, Bi, PIPELINE_BOUND>
21{
22 pub fn bind_vbo<'b, T>(
23 mut self,
24 buffer: &'b VertexBuffer<T>,
25 ) -> RenderPass<'e, Sv, T, Si, Bi, PIPELINE_BOUND>
27 where
28 'b: 'e,
29 T: Vertex + 'static,
30 {
31 self.inner.set_vertex_buffer(0, buffer.inner().slice(..));
32 self.pass()
33 }
34
35 pub fn bind_ibo<'b, T>(
36 mut self,
37 buffer: &'b IndexBuffer<T>,
38 ) -> RenderPass<'e, Sv, Bv, Si, T, PIPELINE_BOUND>
39 where
40 'b: 'e,
41 T: Index + 'static,
42 {
43 self.inner
44 .set_index_buffer(buffer.inner().slice(..), T::FORMAT);
45 self.pass()
46 }
47
48 pub fn bind_shader<'s, V, I>(
49 mut self,
50 shader: &'s Shader<V, I>,
51 ) -> RenderPass<'e, V, Bv, I, Bi, true>
52 where
53 's: 'e,
54 V: Vertex + 'static,
55 I: Index + 'static,
56 {
57 if self.format != shader.format {
58 panic!("Shader output incompatible with this render target");
59 } else {
60 self.inner.set_pipeline(&shader.pipeline);
61 }
62 self.pass()
63 }
64
65 pub fn bind_group<'g>(mut self, bind_group: &'g BindGroup) -> Self
66 where
67 'g: 'e,
68 {
69 self.inner.set_bind_group(0, bind_group, &[]);
70 self.pass()
71 }
72
73 pub fn done(self) -> RenderPass<'e> {
74 self.pass()
75 }
76
77 pub(crate) fn new(inner: wgpu::RenderPass<'e>, format: TextureFormat) -> Self {
78 Self {
79 inner,
80 format,
81 _p: PhantomData::default(),
82 }
83 }
84
85 fn pass<Svn, Bvn, Sin, Bin, const N: bool>(self) -> RenderPass<'e, Svn, Bvn, Sin, Bin, N> {
86 RenderPass {
87 inner: self.inner,
88 format: self.format,
89 _p: PhantomData::default(),
90 }
91 }
92}
93
94impl<'e, V, I> RenderPass<'e, V, V, I, I, true> {
96 pub fn draw(mut self, vertices: Range<u32>, instances: Range<u32>) -> Self {
97 self.inner.draw(vertices, instances);
98 self
99 }
100
101 pub fn draw_indexed(
102 mut self,
103 indices: Range<u32>,
104 base_vertex: i32,
105 instances: Range<u32>,
106 ) -> Self {
107 self.inner.draw_indexed(indices, base_vertex, instances);
108 self
109 }
110
111 }