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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#![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 std::f32::consts::{ TAU };
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 render(&self, time: f32, 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)
};
let scale = Vec3::new(1.0, 1.0, 1.0);
let model = Transformation {
rotation: Vec4::rotation_quaternion(&Vec3::new(0.0, 1.0, 0.0),
time % TAU),
translation: Vec3::new(0.0, 0.0, 0.0),
};
let push_block = VertexPushBlock::<f32> { scale, model };
let size = size_of::<VertexPushBlock::<f32>>();
let push_block_bytes = unsafe {
std::slice::from_raw_parts(&push_block as *const VertexPushBlock<f32>
as *const u8,
size)
};
unsafe {
device.cmd_push_constants(*command_buffer, render.pipeline_layout,
vk::ShaderStageFlags::VERTEX,
0,
push_block_bytes)
};
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)
}
|