1use crate::*;
31use rs_ctypes::*;
32use crate::rs_math3d::*;
33
34pub fn create_color_depth_frame_buffer(driver: &mut DriverPtr, width: usize, height: usize) -> Option<FrameBufferPtr> {
38 let color_tex_desc = SamplerDesc::default(width, height).with_pixel_format(PixelFormat::RGBA8(MinMagFilter::default()));
39 let color_buffer_desc = TextureDesc { sampler_desc: color_tex_desc, payload: None };
40 let color_buffer = driver.create_texture(color_buffer_desc).unwrap();
41
42 let depth_tex_desc = SamplerDesc::default(width, height).with_pixel_format(PixelFormat::D32);
43 let depth_buffer_desc = RenderTargetDesc { sampler_desc: depth_tex_desc, sample_count: 0 };
44 let depth_buffer = driver.create_render_target(depth_buffer_desc).unwrap();
45
46 let fb_desc = FrameBufferDesc {
47 color_attachements: [Some(SurfaceAttachment::Texture(color_buffer)), None, None, None],
48 depth_stencil_attachement: SurfaceAttachment::RenderTarget(depth_buffer)
49 };
50
51 driver.create_frame_buffer(fb_desc)
52}
53
54pub fn create_color_normal_depth_frame_buffer(driver: &mut DriverPtr, width: usize, height: usize) -> Option<FrameBufferPtr> {
58 let normal_tex_desc = SamplerDesc::default(width, height).with_pixel_format(PixelFormat::RGBA32F);
59 let normal_buffer_desc = TextureDesc { sampler_desc: normal_tex_desc, payload: None };
60 let normal_buffer = driver.create_texture(normal_buffer_desc).unwrap();
61
62 let color_tex_desc = SamplerDesc::default(width, height).with_pixel_format(PixelFormat::RGBA8(MinMagFilter::default()));
63 let color_buffer_desc = TextureDesc { sampler_desc: color_tex_desc, payload: None };
64 let color_buffer = driver.create_texture(color_buffer_desc).unwrap();
65
66 let depth_tex_desc = SamplerDesc::default(width, height).with_pixel_format(PixelFormat::D32);
67 let depth_buffer_desc = RenderTargetDesc { sampler_desc: depth_tex_desc, sample_count: 0 };
68 let depth_buffer = driver.create_render_target(depth_buffer_desc).unwrap();
69
70 let fb_desc = FrameBufferDesc {
71 color_attachements: [
72 Some(SurfaceAttachment::Texture(color_buffer)),
73 Some(SurfaceAttachment::Texture(normal_buffer)),
74 None,
75 None],
76 depth_stencil_attachement: SurfaceAttachment::RenderTarget(depth_buffer)
77 };
78 driver.create_frame_buffer(fb_desc)
79}
80
81crate::render_data! {
82 vertex QuadVertex {
83 position : Vec2f,
84 uv : Vec2f,
85 }
86}
87
88pub struct ScreenQuad {
89 vb : DeviceBufferPtr,
90 ib : DeviceBufferPtr,
91 u_pipeline : PipelinePtr,
92 f_pipeline : PipelinePtr,
93}
94
95impl ScreenQuad {
96 pub fn get_vb(&self) -> &DeviceBufferPtr { &self.vb }
97 pub fn get_ib(&self) -> &DeviceBufferPtr { &self.ib }
98}
99
100static COPY_VERTEX_SHADER : &'static str = "
101#version 300 es
102precision highp float;
103in vec2 position;
104in vec2 uv;
105
106out highp vec2 vUV;
107
108void main() {
109 gl_Position = vec4(position, 0.0, 1.0);
110 vUV = uv;
111}";
112
113static COPY_UINT_PIXEL_SHADER : &'static str = "
114#version 300 es
115precision highp float;
116precision highp usampler2D;
117
118in highp vec2 vUV;
119
120uniform usampler2D uTexture;
121
122out vec4 fragColor;
123
124void main() {
125 uvec4 texel = texture(uTexture, vUV);
126 vec4 col = vec4(texel) / 255.0;
127 fragColor = col;
128}";
129
130static COPY_FLOAT_PIXEL_SHADER : &'static str = "
131#version 300 es
132precision highp float;
133precision highp usampler2D;
134
135in highp vec2 vUV;
136
137uniform sampler2D uTexture;
138
139out vec4 fragColor;
140
141void main() {
142 fragColor = texture(uTexture, vUV);
143}";
144
145
146impl ScreenQuad {
147 fn create_copy_shader(driver: &mut DriverPtr, orig_surface_type: OrigSurfaceType) -> ShaderPtr {
148 let shader_desc =
149 ShaderDesc {
150 vertex_shader : String::from(COPY_VERTEX_SHADER),
151 pixel_shader : String::from(
152 match orig_surface_type {
153 OrigSurfaceType::UInt => COPY_UINT_PIXEL_SHADER,
154 OrigSurfaceType::Float => COPY_FLOAT_PIXEL_SHADER,
155 }),
156
157 vertex_attributes : vec!{ QuadVertex::get_attribute_names() },
158 vertex_uniforms : Vec::new(),
159 vertex_surfaces : Vec::new(),
160
161 pixel_uniforms : Vec::new(),
162 pixel_surfaces : Vec::from([String::from("uTexture")]),
163 };
164
165 driver.create_shader(shader_desc).unwrap()
166 }
167
168 fn create_copy_pipeline(driver: &mut DriverPtr, orig_surface_type: OrigSurfaceType) -> PipelinePtr {
169 let vertex_layout = VertexBufferLayout {
170 buffer_id : 0,
171 vertex_attributes : QuadVertex::get_attribute_descriptors(),
172 stride : QuadVertex::stride(),
173 divisor : 0,
174 };
175
176 let model_pipeline_desc = PipelineDesc {
177 primitive_type : PrimitiveType::Triangles,
178 shader : Self::create_copy_shader(driver, orig_surface_type),
179 buffer_layouts : vec! { vertex_layout },
180 uniform_descs : vec! {},
181 index_type : IndexType::UInt32,
182 face_winding : FaceWinding::CCW,
183 cull_mode : CullMode::Winding,
184 depth_write : true,
185 depth_test : true,
186 blend : BlendOp::None,
187 };
188
189 driver.create_pipeline(model_pipeline_desc).unwrap()
190 }
191
192 pub fn new(driver: &mut DriverPtr) -> Self {
193
194 let quad_verts = vec! {
195 QuadVertex { position: Vec2f::new(-1.0, -1.0), uv: Vec2f::new(0.0, 0.0) },
196 QuadVertex { position: Vec2f::new( 1.0, -1.0), uv: Vec2f::new(1.0, 0.0) },
197 QuadVertex { position: Vec2f::new( 1.0, 1.0), uv: Vec2f::new(1.0, 1.0) },
198 QuadVertex { position: Vec2f::new(-1.0, 1.0), uv: Vec2f::new(0.0, 1.0) },
199 };
200
201 let quad_index : Vec<u32> = vec! {
202 0, 1, 2,
203 2, 3, 0,
204 };
205
206 let vb_desc = DeviceBufferDesc::Vertex(Usage::Static(Box::new(quad_verts)));
207 let vb = driver.create_device_buffer(vb_desc).unwrap();
208
209 let ib_desc = DeviceBufferDesc::Index(Usage::Static(Box::new(quad_index)));
210 let ib = driver.create_device_buffer(ib_desc).unwrap();
211
212 Self {
213 vb,
214 ib,
215 u_pipeline: Self::create_copy_pipeline(driver, OrigSurfaceType::UInt),
216 f_pipeline: Self::create_copy_pipeline(driver, OrigSurfaceType::Float),
217 }
218 }
219
220 pub fn render(&self, driver: &mut DriverPtr, tex: &TexturePtr) {
221 let bindings = Bindings {
222 vertex_buffers : vec!{ self.vb.clone() },
223 index_buffer : Some(self.ib.clone()),
224
225 vertex_images : Vec::from([]),
226 pixel_images : Vec::from([tex.clone()]),
227 };
228
229 let pipeline =
230 match tex.desc().sampler_desc.pixel_format.to_orig_surface_type() {
231 OrigSurfaceType::UInt => &self.u_pipeline,
232 OrigSurfaceType::Float => &self.f_pipeline,
233 };
234
235 driver.draw(pipeline, &bindings, core::ptr::null() as *const c_void, 2, 1);
236 }
237}