Actually render a model with texture
This commit is contained in:
parent
e88564d894
commit
e5a30c50a9
@ -7,7 +7,6 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
lazy_static = "1"
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
nalgebra-glm = "0.17"
|
nalgebra-glm = "0.17"
|
||||||
png = "0.17"
|
png = "0.17"
|
||||||
|
16053
resources/viking_room.obj
Normal file
16053
resources/viking_room.obj
Normal file
File diff suppressed because it is too large
Load Diff
BIN
resources/viking_room.png
Normal file
BIN
resources/viking_room.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 MiB |
48
src/app.rs
48
src/app.rs
@ -5,7 +5,6 @@ use data::AppData;
|
|||||||
use structs::*;
|
use structs::*;
|
||||||
|
|
||||||
use ::anyhow::{anyhow, Result};
|
use ::anyhow::{anyhow, Result};
|
||||||
use ::lazy_static::lazy_static;
|
|
||||||
use ::nalgebra_glm as glm;
|
use ::nalgebra_glm as glm;
|
||||||
use ::std::collections::HashSet;
|
use ::std::collections::HashSet;
|
||||||
use ::std::mem::size_of;
|
use ::std::mem::size_of;
|
||||||
@ -30,53 +29,6 @@ pub const DEVICE_EXTENSIONS: &[vk::ExtensionName] = &[vk::KHR_SWAPCHAIN_EXTENSIO
|
|||||||
/// The maximum number of frames that can be processed concurrently.
|
/// The maximum number of frames that can be processed concurrently.
|
||||||
pub const MAX_FRAMES_IN_FLIGHT: usize = 2;
|
pub const MAX_FRAMES_IN_FLIGHT: usize = 2;
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref VERTICES: Vec<Vertex> = vec![
|
|
||||||
Vertex::new(
|
|
||||||
glm::vec3(-0.5, -0.5, 0.0),
|
|
||||||
glm::vec3(1.0, 0.0, 0.0),
|
|
||||||
glm::vec2(1.0, 0.0)
|
|
||||||
),
|
|
||||||
Vertex::new(
|
|
||||||
glm::vec3(0.5, -0.5, 0.0),
|
|
||||||
glm::vec3(0.0, 1.0, 0.0),
|
|
||||||
glm::vec2(0.0, 0.0)
|
|
||||||
),
|
|
||||||
Vertex::new(
|
|
||||||
glm::vec3(0.5, 0.5, 0.0),
|
|
||||||
glm::vec3(0.0, 0.0, 1.0),
|
|
||||||
glm::vec2(0.0, 1.0)
|
|
||||||
),
|
|
||||||
Vertex::new(
|
|
||||||
glm::vec3(-0.5, 0.5, 0.0),
|
|
||||||
glm::vec3(1.0, 1.0, 1.0),
|
|
||||||
glm::vec2(1.0, 1.0)
|
|
||||||
),
|
|
||||||
Vertex::new(
|
|
||||||
glm::vec3(-0.5, -0.5, -0.5),
|
|
||||||
glm::vec3(1.0, 0.0, 0.0),
|
|
||||||
glm::vec2(1.0, 0.0)
|
|
||||||
),
|
|
||||||
Vertex::new(
|
|
||||||
glm::vec3(0.5, -0.5, -0.5),
|
|
||||||
glm::vec3(0.0, 1.0, 0.0),
|
|
||||||
glm::vec2(0.0, 0.0)
|
|
||||||
),
|
|
||||||
Vertex::new(
|
|
||||||
glm::vec3(0.5, 0.5, -0.5),
|
|
||||||
glm::vec3(0.0, 0.0, 1.0),
|
|
||||||
glm::vec2(0.0, 1.0)
|
|
||||||
),
|
|
||||||
Vertex::new(
|
|
||||||
glm::vec3(-0.5, 0.5, -0.5),
|
|
||||||
glm::vec3(1.0, 1.0, 1.0),
|
|
||||||
glm::vec2(1.0, 1.0)
|
|
||||||
),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const INDICES: &[u16] = &[0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4];
|
|
||||||
|
|
||||||
/// Our Vulkan app.
|
/// Our Vulkan app.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct App {
|
pub struct App {
|
||||||
|
@ -4,9 +4,12 @@ use crate::VALIDATION_ENABLED;
|
|||||||
|
|
||||||
use ::anyhow::{anyhow, Result};
|
use ::anyhow::{anyhow, Result};
|
||||||
use ::log::*;
|
use ::log::*;
|
||||||
|
use ::std::collections::HashMap;
|
||||||
use ::std::collections::HashSet;
|
use ::std::collections::HashSet;
|
||||||
use ::std::ffi::CStr;
|
use ::std::ffi::CStr;
|
||||||
use ::std::fs::File;
|
use ::std::fs::File;
|
||||||
|
use ::std::hash::{Hash, Hasher};
|
||||||
|
use ::std::io::BufReader;
|
||||||
use ::std::os::raw::c_void;
|
use ::std::os::raw::c_void;
|
||||||
use ::std::ptr::copy_nonoverlapping as memcpy;
|
use ::std::ptr::copy_nonoverlapping as memcpy;
|
||||||
use ::vulkanalia::prelude::v1_0::*;
|
use ::vulkanalia::prelude::v1_0::*;
|
||||||
@ -71,6 +74,9 @@ pub(crate) struct AppData {
|
|||||||
texture_image_memory: vk::DeviceMemory,
|
texture_image_memory: vk::DeviceMemory,
|
||||||
texture_image_view: vk::ImageView,
|
texture_image_view: vk::ImageView,
|
||||||
texture_sampler: vk::Sampler,
|
texture_sampler: vk::Sampler,
|
||||||
|
// Model
|
||||||
|
vertices: Vec<Vertex>,
|
||||||
|
indices: Vec<u32>,
|
||||||
// Buffers
|
// Buffers
|
||||||
vertex_buffer: vk::Buffer,
|
vertex_buffer: vk::Buffer,
|
||||||
vertex_buffer_memory: vk::DeviceMemory,
|
vertex_buffer_memory: vk::DeviceMemory,
|
||||||
@ -117,6 +123,7 @@ impl AppData {
|
|||||||
self.create_texture_image(&instance, &device)?;
|
self.create_texture_image(&instance, &device)?;
|
||||||
self.create_texture_image_view(&device)?;
|
self.create_texture_image_view(&device)?;
|
||||||
self.create_texture_sampler(&device)?;
|
self.create_texture_sampler(&device)?;
|
||||||
|
self.load_model()?;
|
||||||
self.create_vertex_buffer(&instance, &device)?;
|
self.create_vertex_buffer(&instance, &device)?;
|
||||||
self.create_index_buffer(&instance, &device)?;
|
self.create_index_buffer(&instance, &device)?;
|
||||||
self.create_uniform_buffers(&instance, &device)?;
|
self.create_uniform_buffers(&instance, &device)?;
|
||||||
@ -799,7 +806,7 @@ impl AppData {
|
|||||||
|
|
||||||
fn create_texture_image(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
fn create_texture_image(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||||
// Load the image
|
// Load the image
|
||||||
let image = File::open("resources/texture.png")?;
|
let image = File::open("resources/viking_room.png")?;
|
||||||
|
|
||||||
let decoder = png::Decoder::new(image);
|
let decoder = png::Decoder::new(image);
|
||||||
let mut reader = decoder.read_info()?;
|
let mut reader = decoder.read_info()?;
|
||||||
@ -903,13 +910,55 @@ impl AppData {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================
|
||||||
|
// Model
|
||||||
|
//================================================
|
||||||
|
|
||||||
|
unsafe fn load_model(&mut self) -> Result<()> {
|
||||||
|
let mut reader = BufReader::new(File::open("resources/viking_room.obj")?);
|
||||||
|
|
||||||
|
let (models, _) = tobj::load_obj_buf(
|
||||||
|
&mut reader,
|
||||||
|
&tobj::LoadOptions {
|
||||||
|
triangulate: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
|_| Ok(Default::default()),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
for model in &models {
|
||||||
|
for index in &model.mesh.indices {
|
||||||
|
let pos_offset = (3 * index) as usize;
|
||||||
|
let tex_coord_offset = (2 * index) as usize;
|
||||||
|
|
||||||
|
let vertex = Vertex::new(
|
||||||
|
glm::vec3(
|
||||||
|
model.mesh.positions[pos_offset],
|
||||||
|
model.mesh.positions[pos_offset + 1],
|
||||||
|
model.mesh.positions[pos_offset + 2],
|
||||||
|
),
|
||||||
|
glm::vec3(1.0, 1.0, 1.0),
|
||||||
|
glm::vec2(
|
||||||
|
model.mesh.texcoords[tex_coord_offset],
|
||||||
|
1.0 - model.mesh.texcoords[tex_coord_offset + 1],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.vertices.push(vertex);
|
||||||
|
self.indices.push(self.indices.len() as u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
//================================================
|
//================================================
|
||||||
// Buffers
|
// Buffers
|
||||||
//================================================
|
//================================================
|
||||||
|
|
||||||
unsafe fn create_vertex_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
unsafe fn create_vertex_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||||
// Create staging buffer
|
// Create staging buffer
|
||||||
let size = (size_of::<Vertex>() * VERTICES.len()) as u64;
|
let size = (size_of::<Vertex>() * self.vertices.len()) as u64;
|
||||||
let (staging_buffer, staging_buffer_memory) = self.create_buffer(
|
let (staging_buffer, staging_buffer_memory) = self.create_buffer(
|
||||||
instance,
|
instance,
|
||||||
device,
|
device,
|
||||||
@ -920,7 +969,7 @@ impl AppData {
|
|||||||
|
|
||||||
let memory =
|
let memory =
|
||||||
device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?;
|
device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?;
|
||||||
memcpy(VERTICES.as_ptr(), memory.cast(), VERTICES.len());
|
memcpy(self.vertices.as_ptr(), memory.cast(), self.vertices.len());
|
||||||
device.unmap_memory(staging_buffer_memory);
|
device.unmap_memory(staging_buffer_memory);
|
||||||
|
|
||||||
// Create vertex buffer
|
// Create vertex buffer
|
||||||
@ -946,7 +995,7 @@ impl AppData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn create_index_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
unsafe fn create_index_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||||
let size = (size_of::<u16>() * INDICES.len()) as u64;
|
let size = (size_of::<u32>() * self.indices.len()) as u64;
|
||||||
let (staging_buffer, staging_buffer_memory) = self.create_buffer(
|
let (staging_buffer, staging_buffer_memory) = self.create_buffer(
|
||||||
instance,
|
instance,
|
||||||
device,
|
device,
|
||||||
@ -957,7 +1006,7 @@ impl AppData {
|
|||||||
|
|
||||||
let memory =
|
let memory =
|
||||||
device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?;
|
device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?;
|
||||||
memcpy(INDICES.as_ptr(), memory.cast(), INDICES.len());
|
memcpy(self.indices.as_ptr(), memory.cast(), self.indices.len());
|
||||||
device.unmap_memory(staging_buffer_memory);
|
device.unmap_memory(staging_buffer_memory);
|
||||||
|
|
||||||
let (index_buffer, index_buffer_memory) = self.create_buffer(
|
let (index_buffer, index_buffer_memory) = self.create_buffer(
|
||||||
@ -1128,7 +1177,7 @@ impl AppData {
|
|||||||
*command_buffer,
|
*command_buffer,
|
||||||
self.index_buffer,
|
self.index_buffer,
|
||||||
0,
|
0,
|
||||||
vk::IndexType::UINT16,
|
vk::IndexType::UINT32,
|
||||||
);
|
);
|
||||||
device.cmd_bind_descriptor_sets(
|
device.cmd_bind_descriptor_sets(
|
||||||
*command_buffer,
|
*command_buffer,
|
||||||
@ -1138,7 +1187,7 @@ impl AppData {
|
|||||||
&[self.descriptor_sets[i]],
|
&[self.descriptor_sets[i]],
|
||||||
&[],
|
&[],
|
||||||
);
|
);
|
||||||
device.cmd_draw_indexed(*command_buffer, INDICES.len() as u32, 1, 0, 0, 0);
|
device.cmd_draw_indexed(*command_buffer, self.indices.len() as u32, 1, 0, 0, 0);
|
||||||
device.cmd_end_render_pass(*command_buffer);
|
device.cmd_end_render_pass(*command_buffer);
|
||||||
|
|
||||||
device.end_command_buffer(*command_buffer)?;
|
device.end_command_buffer(*command_buffer)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user