Actually render a model with texture
This commit is contained in:
parent
e88564d894
commit
e5a30c50a9
@ -7,7 +7,6 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
nalgebra-glm = "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 ::anyhow::{anyhow, Result};
|
||||
use ::lazy_static::lazy_static;
|
||||
use ::nalgebra_glm as glm;
|
||||
use ::std::collections::HashSet;
|
||||
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.
|
||||
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.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct App {
|
||||
|
@ -4,9 +4,12 @@ use crate::VALIDATION_ENABLED;
|
||||
|
||||
use ::anyhow::{anyhow, Result};
|
||||
use ::log::*;
|
||||
use ::std::collections::HashMap;
|
||||
use ::std::collections::HashSet;
|
||||
use ::std::ffi::CStr;
|
||||
use ::std::fs::File;
|
||||
use ::std::hash::{Hash, Hasher};
|
||||
use ::std::io::BufReader;
|
||||
use ::std::os::raw::c_void;
|
||||
use ::std::ptr::copy_nonoverlapping as memcpy;
|
||||
use ::vulkanalia::prelude::v1_0::*;
|
||||
@ -71,6 +74,9 @@ pub(crate) struct AppData {
|
||||
texture_image_memory: vk::DeviceMemory,
|
||||
texture_image_view: vk::ImageView,
|
||||
texture_sampler: vk::Sampler,
|
||||
// Model
|
||||
vertices: Vec<Vertex>,
|
||||
indices: Vec<u32>,
|
||||
// Buffers
|
||||
vertex_buffer: vk::Buffer,
|
||||
vertex_buffer_memory: vk::DeviceMemory,
|
||||
@ -117,6 +123,7 @@ impl AppData {
|
||||
self.create_texture_image(&instance, &device)?;
|
||||
self.create_texture_image_view(&device)?;
|
||||
self.create_texture_sampler(&device)?;
|
||||
self.load_model()?;
|
||||
self.create_vertex_buffer(&instance, &device)?;
|
||||
self.create_index_buffer(&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<()> {
|
||||
// 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 mut reader = decoder.read_info()?;
|
||||
@ -903,13 +910,55 @@ impl AppData {
|
||||
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
|
||||
//================================================
|
||||
|
||||
unsafe fn create_vertex_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
// 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(
|
||||
instance,
|
||||
device,
|
||||
@ -920,7 +969,7 @@ impl AppData {
|
||||
|
||||
let memory =
|
||||
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);
|
||||
|
||||
// Create vertex buffer
|
||||
@ -946,7 +995,7 @@ impl AppData {
|
||||
}
|
||||
|
||||
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(
|
||||
instance,
|
||||
device,
|
||||
@ -957,7 +1006,7 @@ impl AppData {
|
||||
|
||||
let memory =
|
||||
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);
|
||||
|
||||
let (index_buffer, index_buffer_memory) = self.create_buffer(
|
||||
@ -1128,7 +1177,7 @@ impl AppData {
|
||||
*command_buffer,
|
||||
self.index_buffer,
|
||||
0,
|
||||
vk::IndexType::UINT16,
|
||||
vk::IndexType::UINT32,
|
||||
);
|
||||
device.cmd_bind_descriptor_sets(
|
||||
*command_buffer,
|
||||
@ -1138,7 +1187,7 @@ impl AppData {
|
||||
&[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.end_command_buffer(*command_buffer)?;
|
||||
|
Loading…
Reference in New Issue
Block a user