summary refs log tree commit diff
path: root/src/graphics/model.rs
blob: 053818fae734fb6b3ed156b9659831a4d2d256ff (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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#![deny(unsafe_code)]
use crate::error::*;
use crate::graphics::{ Permanent, Render };
use crate::graphics::util::init_buffer;
use crate::linear_algebra::{ Vec3, Vec4, Transformation };
use crate::shader_data::{ Vertex, VertexPushBlock };

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


#[derive(Debug)]
pub struct Model {
  pub vertex_buffer: vk::Buffer,
  vertex_buffer_memory: vk::DeviceMemory,

  pub index_buffer: vk::Buffer,
  index_buffer_memory: vk::DeviceMemory,
  pub index_count: usize,
}


impl Model {
  pub fn new(vertices: Vec<Vertex<f32>>, indices: Vec<u32>,
             permanent: &Permanent)
      -> Result<Self>
  {
    let device = &permanent.device;
    let instance = &permanent.instance;
    let graphics_queue = &permanent.graphics_queue;
    let transient_command_pool = &permanent.transient_command_pool;

    let index_count = indices.len();

    let (vertex_buffer, vertex_buffer_memory)
            = init_vertex_buffer(vertices, instance, device, graphics_queue,
                                 &transient_command_pool)?;
    let (index_buffer, index_buffer_memory)
            = init_index_buffer(indices, instance, device, graphics_queue,
                                &transient_command_pool)?;

    Ok(Model {
      vertex_buffer,
      vertex_buffer_memory,
      index_buffer,
      index_buffer_memory,
      index_count,
    })
  }

  #[allow(unsafe_code)]
  pub fn destroy(self, device: &Device) {
    unsafe { device.destroy_buffer(self.vertex_buffer, None) };
    unsafe { device.free_memory(self.vertex_buffer_memory, None) };

    unsafe { device.destroy_buffer(self.index_buffer, None) };
    unsafe { device.free_memory(self.index_buffer_memory, None) };
  }

  #[allow(unsafe_code)]
  pub fn make_active(&self, device: &Device, render: &Render,
                     command_buffer: &vk::CommandBuffer)
  {
    unsafe {
      device.cmd_bind_vertex_buffers(*command_buffer, 0,
                                     &[self.vertex_buffer], &[0])
    };

    unsafe {
      device.cmd_bind_index_buffer(*command_buffer, self.index_buffer,
                                   0, vk::IndexType::UINT32)
    };
  }

  #[allow(unsafe_code)]
  pub fn render(&self, device: &Device, render: &Render,
                command_buffer: &vk::CommandBuffer)
  {
    unsafe {
      device.cmd_draw_indexed(*command_buffer, self.index_count as u32,
                              1, 0, 0, 0)
    };
  }
}


fn init_vertex_buffer(vertices: Vec<Vertex<f32>>, instance: &Instance,
                      device: &Device, queue: &vk::Queue,
                      command_pool: &vk::CommandPool)
    -> Result<(vk::Buffer, vk::DeviceMemory)>
{
  init_buffer(instance, device, queue, command_pool,
              vk::BufferUsageFlags::VERTEX_BUFFER, &vertices)
}


fn init_index_buffer(indices: Vec<u32>, instance: &Instance, device: &Device,
                     queue: &vk::Queue, command_pool: &vk::CommandPool)
    -> Result<(vk::Buffer, vk::DeviceMemory)>
{
  init_buffer(instance, device, queue, command_pool,
              vk::BufferUsageFlags::INDEX_BUFFER, &indices)
}