mesh loading, broken mesh

This commit is contained in:
zomseffen 2024-04-26 18:22:14 +02:00
parent f6276bfdf6
commit 31d4a139ef
9 changed files with 16153 additions and 27 deletions

16053
resources/viking_room.obj Normal file

File diff suppressed because it is too large Load diff

BIN
resources/viking_room.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

View file

@ -1,7 +1,14 @@
use vulkanalia::prelude::v1_0::*;
use crate::vertex;
// The Vulkan handles and associated properties used by our Vulkan app.
#[derive(Clone, Debug, Default)]
pub struct AppData {
pub vertices: Vec<vertex::Vertex>,
pub indices: Vec<u32>,
pub surface: vk::SurfaceKHR,
pub messenger: vk::DebugUtilsMessengerEXT,
pub physical_device: vk::PhysicalDevice,

View file

@ -5,32 +5,12 @@ use vulkanalia::prelude::v1_0::*;
use std::mem::size_of;
use std::ptr::copy_nonoverlapping as memcpy;
use cgmath::{vec2, vec3};
pub type Mat4 = cgmath::Matrix4<f32>;
use crate::app_data;
use crate::vertex;
use crate::command_buffer;
static VERTICES: [vertex::Vertex; 8] = [
vertex::Vertex::new(vec3(-0.5, -0.5, 0.0), vec3(1.0, 0.0, 0.0), vec2(1.0, 0.0)),
vertex::Vertex::new(vec3(0.5, -0.5, 0.0), vec3(0.0, 1.0, 0.0), vec2(0.0, 0.0)),
vertex::Vertex::new(vec3(0.5, 0.5, 0.0), vec3(0.0, 0.0, 1.0), vec2(0.0, 1.0)),
vertex::Vertex::new(vec3(-0.5, 0.5, 0.0), vec3(1.0, 1.0, 1.0), vec2(1.0, 1.0)),
vertex::Vertex::new(vec3(-0.5, -0.5, -0.5), vec3(1.0, 0.0, 0.0), vec2(1.0, 0.0)),
vertex::Vertex::new(vec3(0.5, -0.5, -0.5), vec3(0.0, 1.0, 0.0), vec2(0.0, 0.0)),
vertex::Vertex::new(vec3(0.5, 0.5, -0.5), vec3(0.0, 0.0, 1.0), vec2(0.0, 1.0)),
vertex::Vertex::new(vec3(-0.5, 0.5, -0.5), vec3(1.0, 1.0, 1.0), vec2(1.0, 1.0)),
];
pub const INDICES: &[u16] = &[
0, 1, 2,
2, 3, 0,
4, 5, 6,
6, 7, 4,
];
pub unsafe fn create_buffer(
instance: &Instance,
device: &Device,
@ -69,7 +49,7 @@ pub unsafe fn create_vertex_buffer(
device: &Device,
data: &mut app_data::AppData,
) -> Result<()> {
let size = (size_of::<vertex::Vertex>() * VERTICES.len()) as u64;
let size = (size_of::<vertex::Vertex>() * data.vertices.len()) as u64;
let (staging_buffer, staging_buffer_memory) = create_buffer(
instance,
@ -87,7 +67,7 @@ pub unsafe fn create_vertex_buffer(
vk::MemoryMapFlags::empty(),
)?;
memcpy(VERTICES.as_ptr(), memory.cast(), VERTICES.len());
memcpy(data.vertices.as_ptr(), memory.cast(), data.vertices.len());
device.unmap_memory(staging_buffer_memory);
@ -150,7 +130,7 @@ pub unsafe fn create_index_buffer(
device: &Device,
data: &mut app_data::AppData,
) -> Result<()> {
let size = (size_of::<u16>() * INDICES.len()) as u64;
let size = (size_of::<u16>() * data.indices.len()) as u64;
let (staging_buffer, staging_buffer_memory) = create_buffer(
instance,
@ -168,7 +148,7 @@ pub unsafe fn create_index_buffer(
vk::MemoryMapFlags::empty(),
)?;
memcpy(INDICES.as_ptr(), memory.cast(), INDICES.len());
memcpy(data.indices.as_ptr(), memory.cast(), data.indices.len());
device.unmap_memory(staging_buffer_memory);

View file

@ -4,7 +4,6 @@ use vulkanalia::prelude::v1_0::*;
use crate::app_data;
use crate::buffer;
use crate::queue_family_indices;
pub unsafe fn create_command_pool(
@ -82,7 +81,7 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
&[],
);
device.cmd_draw_indexed(*command_buffer, buffer::INDICES.len() as u32, 1, 0, 0, 0);
device.cmd_draw_indexed(*command_buffer, data.indices.len() as u32, 1, 0, 0, 0);
device.cmd_end_render_pass(*command_buffer);

View file

@ -18,7 +18,7 @@ pub unsafe fn create_texture_image(
device: &Device,
data: &mut app_data::AppData,
) -> Result<()> {
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()?;

60
src/load_model.rs Normal file
View file

@ -0,0 +1,60 @@
use anyhow::Result;
use std::fs::File;
use std::collections::HashMap;
use std::io::BufReader;
use crate::app_data;
use crate::vertex;
use cgmath::{vec3, vec2};
pub fn load_model(data: &mut app_data::AppData) -> Result<()> {
// Model
let mut reader = BufReader::new(File::open("./resources/viking_room.obj").expect("file not found"));
let (models, _) = tobj::load_obj_buf(
&mut reader,
&tobj::LoadOptions {
triangulate: true,
..Default::default()
},
|_| Ok(Default::default()),
)?;
// Vertices / Indices
let mut unique_vertices = HashMap::new();
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::Vertex {
pos: vec3(
model.mesh.positions[pos_offset],
model.mesh.positions[pos_offset + 1],
model.mesh.positions[pos_offset + 2],
),
color: vec3(1.0, 1.0, 1.0),
tex_coord: vec2(
model.mesh.texcoords[tex_coord_offset],
1.0 - model.mesh.texcoords[tex_coord_offset + 1],
),
};
if let Some(index) = unique_vertices.get(&vertex) {
data.indices.push(*index as u32);
} else {
let index = data.vertices.len();
unique_vertices.insert(vertex, index);
data.vertices.push(vertex);
data.indices.push(index as u32);
}
}
}
Ok(())
}

View file

@ -42,6 +42,7 @@ pub mod buffer;
pub mod image;
pub mod command_buffer;
pub mod depth_buffer;
pub mod load_model;
const PORTABILITY_MACOS_VERSION: Version = Version::new(1, 3, 216);
const VALIDATION_ENABLED: bool =
@ -116,6 +117,7 @@ impl App {
let loader = LibloadingLoader::new(LIBRARY)?;
let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
let mut data = app_data::AppData::default();
load_model::load_model(&mut data)?;
let instance = create_instance(window, &entry, &mut data)?;
data.surface = vk_window::create_surface(&instance, &window, &window)?;
pick_physical_device(&instance, &mut data)?;

View file

@ -1,5 +1,6 @@
use vulkanalia::prelude::v1_0::*;
use std::hash::{Hash, Hasher};
use std::mem::size_of;
use cgmath;
@ -52,3 +53,27 @@ impl Vertex {
[pos, color, tex_coord]
}
}
impl PartialEq for Vertex {
fn eq(&self, other: &Self) -> bool {
self.pos == other.pos
&& self.color == other.color
&& self.tex_coord == other.tex_coord
}
}
impl Eq for Vertex {}
impl Hash for Vertex {
fn hash<H: Hasher>(&self, state: &mut H) {
self.pos[0].to_bits().hash(state);
self.pos[1].to_bits().hash(state);
self.pos[2].to_bits().hash(state);
self.color[0].to_bits().hash(state);
self.color[1].to_bits().hash(state);
self.color[2].to_bits().hash(state);
self.tex_coord[0].to_bits().hash(state);
self.tex_coord[1].to_bits().hash(state);
}
}