Fractal/src/fractal.rs

251 lines
7.5 KiB
Rust
Raw Normal View History

2020-11-23 17:41:14 +00:00
use std::{mem, sync::Arc};
use context::{prelude::*, ContextObject};
2020-11-24 15:38:29 +00:00
#[derive(Debug, Clone)]
struct ShaderInfo {
max_iter: i32,
size: f32,
time: f32,
factor: f32,
2020-11-26 18:12:46 +00:00
width: f32,
height: f32,
2020-11-24 15:38:29 +00:00
}
#[derive(Clone)]
struct Vertex {
position: [f32; 2],
uv: [f32; 2],
}
2020-11-23 17:41:14 +00:00
pub struct Fractal {
context: Arc<Context>,
descriptor_set: Arc<DescriptorSet>,
pipeline: Arc<Pipeline>,
render_target: RenderTarget,
2020-11-24 15:38:29 +00:00
vertex_buffer: Arc<Buffer<Vertex>>,
descriptor_buffer: Arc<Buffer<ShaderInfo>>,
2020-11-23 17:41:14 +00:00
}
impl Fractal {
pub fn new(context: &Arc<Context>) -> VerboseResult<Arc<Self>> {
let render_core = context.render_core();
let render_target = RenderTarget::builder()
.add_sub_pass(
SubPass::builder(render_core.width(), render_core.height())
.set_prepared_targets(
render_core.images()?.single()?,
0,
[0.0, 0.0, 0.0, 0.0],
true,
)
.build(context.device(), context.queue())?,
)
.build(context.device())?;
let descriptor_layout = DescriptorSetLayout::builder()
.add_layout_binding(
0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_FRAGMENT_BIT,
0,
)
.build(context.device().clone())?;
let pipeline_layout = PipelineLayout::builder()
.add_descriptor_set_layout(&descriptor_layout)
.build(context.device().clone())?;
let pipeline = Pipeline::new_graphics()
.default_rasterization(VK_CULL_MODE_FRONT_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE)
.default_multisample(VK_SAMPLE_COUNT_1_BIT)
.input_assembly(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false)
.default_color_blend(vec![VkPipelineColorBlendAttachmentState::default()])
.set_vertex_shader(
ShaderModule::from_slice(
context.device().clone(),
include_bytes!("fractal.vert.spv"),
ShaderType::Vertex,
)?,
vec![VkVertexInputBindingDescription {
binding: 0,
inputRate: VK_VERTEX_INPUT_RATE_VERTEX,
2020-11-24 15:38:29 +00:00
stride: mem::size_of::<Vertex>() as u32,
2020-11-23 17:41:14 +00:00
}],
2020-11-24 15:38:29 +00:00
vec![
VkVertexInputAttributeDescription {
location: 0,
binding: 0,
format: VK_FORMAT_R32G32_SFLOAT,
offset: 0,
},
VkVertexInputAttributeDescription {
location: 1,
binding: 0,
format: VK_FORMAT_R32G32_SFLOAT,
offset: 8,
},
],
2020-11-23 17:41:14 +00:00
)
.set_fragment_shader(ShaderModule::from_slice(
context.device().clone(),
include_bytes!("fractal.frag.spv"),
ShaderType::Fragment,
)?)
.add_viewport(VkViewport {
x: 0.0,
y: 0.0,
width: render_core.width() as f32,
height: render_core.height() as f32,
minDepth: 0.0,
maxDepth: 1.0,
})
.add_scissor(VkRect2D {
offset: VkOffset2D { x: 0, y: 0 },
extent: VkExtent2D {
width: render_core.width(),
height: render_core.height(),
},
})
.build(
context.device().clone(),
&pipeline_layout,
render_target.render_pass(),
0,
)?;
let descriptor_set = DescriptorPool::builder()
.set_layout(descriptor_layout)
.build(context.device().clone())?
.prepare_set()
.allocate()?;
let vertex_buffer = Buffer::builder()
.set_data(&[
2020-11-24 15:38:29 +00:00
Vertex {
position: [-1.0, -1.0],
uv: [0.0, 0.0],
},
Vertex {
position: [1.0, -1.0],
uv: [1.0, 0.0],
},
Vertex {
position: [1.0, 1.0],
uv: [1.0, 1.0],
},
Vertex {
position: [1.0, 1.0],
uv: [1.0, 1.0],
},
Vertex {
position: [-1.0, 1.0],
uv: [0.0, 1.0],
},
Vertex {
position: [-1.0, -1.0],
uv: [0.0, 0.0],
},
2020-11-23 17:41:14 +00:00
])
.set_memory_usage(MemoryUsage::CpuOnly)
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
.build(context.device().clone())?;
2020-11-24 15:38:29 +00:00
let shader_info = Buffer::builder()
.set_data(&[ShaderInfo {
max_iter: 1000,
size: 0.001,
time: 0.0,
factor: 1.0,
2020-11-26 18:12:46 +00:00
width: render_core.width() as f32,
height: render_core.height() as f32,
2020-11-24 15:38:29 +00:00
}])
.set_memory_usage(MemoryUsage::CpuOnly)
.set_usage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
.build(context.device().clone())?;
descriptor_set.update(&[DescriptorWrite::uniform_buffers(0, &[&shader_info])])?;
2020-11-23 17:41:14 +00:00
Ok(Arc::new(Self {
context: context.clone(),
descriptor_set,
pipeline,
render_target,
vertex_buffer,
2020-11-24 15:38:29 +00:00
descriptor_buffer: shader_info,
2020-11-23 17:41:14 +00:00
}))
}
}
impl ContextObject for Fractal {
fn name(&self) -> &str {
"Fractal"
}
fn update(&self) -> VerboseResult<()> {
2020-11-24 15:38:29 +00:00
let mut mapping = self.descriptor_buffer.map_complete()?;
mapping[0].time = self.context.time().as_secs_f32();
2020-11-23 17:41:14 +00:00
Ok(())
}
fn event(&self, event: Event) -> VerboseResult<()> {
match event {
Event::KeyDown(key) => match key {
Keycode::Escape => self.context.close()?,
_ => (),
},
_ => (),
}
Ok(())
}
}
impl TScene for Fractal {
fn update(&self) -> VerboseResult<()> {
Ok(())
}
fn process(
&self,
buffer_recorder: &mut CommandBufferRecorder<'_>,
indices: &TargetMode<usize>,
) -> VerboseResult<()> {
match indices {
TargetMode::Single(index) => {
self.render_target
.begin(buffer_recorder, VK_SUBPASS_CONTENTS_INLINE, *index);
buffer_recorder.bind_pipeline(&self.pipeline)?;
buffer_recorder.bind_descriptor_sets_minimal(&[&self.descriptor_set])?;
buffer_recorder.bind_vertex_buffer(&self.vertex_buffer);
buffer_recorder.draw_complete_single_instance(self.vertex_buffer.size() as u32);
self.render_target.end(buffer_recorder);
}
TargetMode::Stereo(_, _) => unimplemented!(),
}
Ok(())
}
fn resize(&self) -> VerboseResult<()> {
2020-11-26 18:12:46 +00:00
let mut mapping = self.descriptor_buffer.map_complete()?;
2020-11-23 17:41:14 +00:00
2020-11-26 18:12:46 +00:00
mapping[0].width = self.context.render_core().width() as f32;
mapping[0].height = self.context.render_core().height() as f32;
todo!("resize of FB is still missing");
// Ok(())
2020-11-23 17:41:14 +00:00
}
}