summary refs log tree commit diff
path: root/src/graphics/scene.rs
blob: 9631dba203bab43c7f1d5df5ddf1a321f38f4f3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#![deny(unsafe_code)]
use crate::error::*;
use crate::graphics::Render;

use vulkanalia::Device;
use vulkanalia::vk::{ self, HasBuilder, DeviceV1_0 };


#[allow(unsafe_code)]
pub fn generate_scene_commands<'a>(image_index: usize, time: f32,
                                   render: &'a Render,
                                   device: &Device, extent: &vk::Extent2D)
    -> Result<&'a vk::CommandBuffer>
{
  let frame = &render.per_frame[image_index];
  let command_buffer = &frame.command_buffer;
  let framebuffer = &frame.framebuffer;
  let descriptor_set = &frame.descriptor_set;

  let inheritance_info = vk::CommandBufferInheritanceInfo::builder();

  let command_buffer_begin_info = vk::CommandBufferBeginInfo::builder()
          .flags(vk::CommandBufferUsageFlags::empty())
          .inheritance_info(&inheritance_info);

  unsafe {
    device.begin_command_buffer(*command_buffer, &command_buffer_begin_info)
  }?;

  let render_area = vk::Rect2D::builder()
          .offset(vk::Offset2D::default())
          .extent(*extent);

  let color_clear_value = vk::ClearValue {
    color: vk::ClearColorValue {
      float32: [0.0, 0.0, 0.0, 1.0]
    }
  };
  let depth_clear_value = vk::ClearValue {
    depth_stencil: vk::ClearDepthStencilValue {
      depth: 1.0,
      stencil: 0,
    }
  };
  let clear_values = [color_clear_value, depth_clear_value];

  let begin_pass_info = vk::RenderPassBeginInfo::builder()
          .render_pass(render.render_pass)
          .framebuffer(*framebuffer)
          .render_area(render_area)
          .clear_values(&clear_values);

  unsafe {
    device.cmd_begin_render_pass(*command_buffer, &begin_pass_info,
                                 vk::SubpassContents::INLINE)
  };

  unsafe {
    device.cmd_bind_pipeline(*command_buffer,
                             vk::PipelineBindPoint::GRAPHICS,
                             render.pipeline)
  };

  //   Please notice the magic constant 0. This is a zero-based index into
  // the array of descriptor set layouts passed to create_pipeline_layout()
  // in init_pipeline() in render.rs.
  unsafe {
    device.cmd_bind_descriptor_sets(*command_buffer,
                                    vk::PipelineBindPoint::GRAPHICS,
                                    render.pipeline_layout,
                                    0,
                                    &[*descriptor_set],
                                    &[])
  };

  if let Some(texture) = &render.texture {
    texture.make_active(device, render, command_buffer);
  }

  if let Some(model) = &render.model {
    model.render(time, device, render, command_buffer);
  }

  unsafe { device.cmd_end_render_pass(*command_buffer) };

  unsafe { device.end_command_buffer(*command_buffer) }?;

  Ok(command_buffer)
}