diff --git a/src/game/mod.rs b/src/game/mod.rs index 46b1318..5f25573 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,4 +1,6 @@ +use std::{convert::TryInto, io::Read, time::SystemTime}; + use cgmath::{Deg, InnerSpace, Quaternion, Rotation3}; use winit::event::Event; @@ -125,7 +127,7 @@ impl TestGame { let mut mesh_handles = Vec::new(); // Load file - let (meshes, textures) = mesh::load_mesh(gltf_path, self.log_config.mesh_load_info).unwrap(); + let (meshes, document) = mesh::load_mesh(gltf_path, self.log_config.mesh_load_info).unwrap(); for cpu_mesh in meshes.into_iter() { // Convert file texture id to game texture id @@ -143,10 +145,36 @@ impl TestGame { mesh_handles.push(mesh_handle); } - textures.iter().for_each(|tex| { - renderer.upload_texture(tex, renderer.device.clone()); + for doc_image in document.images() + { + let texture_start_time = SystemTime::now(); + + // Load file + let mut tex_file = std::fs::File::open(format!("models/textures/{}.dds", doc_image.name().unwrap())).unwrap(); + let mut tex_bytes: Vec = vec![]; + tex_file.read_to_end(&mut tex_bytes).unwrap(); + + // Parse DDS + let tex_height = u32::from_ne_bytes(tex_bytes[12..16].try_into().unwrap()); + let tex_width = u32::from_ne_bytes(tex_bytes[16..20].try_into().unwrap()); + let tex_byte_count = u32::from_ne_bytes(tex_bytes[20..24].try_into().unwrap()); + let pixel_format_flags = u32::from_ne_bytes(tex_bytes[80..84].try_into().unwrap()); + let pixel_format_name: [u8; 4] = tex_bytes[84..88].try_into().unwrap(); + let is_dxt1 = pixel_format_name == [0x44, 0x58, 0x54, 0x31]; // [D,X,T,1] + + assert!(pixel_format_flags == 0x00000004); + assert!(is_dxt1); + println!("Texture width: {}, height: {}, bytes: {}", tex_width, tex_height, tex_byte_count); + + let data_start: usize = 124; + let data_end: usize = data_start + tex_byte_count as usize; + renderer.upload_texture(&tex_bytes[data_start..data_end], tex_width, tex_height, vulkano::format::Format::BC1_RGBASrgbBlock, renderer.device.clone()); self.texture_index_counter += 1; - }); + + if self.log_config.mesh_load_info { + println!("Uploading texture took {:?}s", texture_start_time.elapsed().unwrap().as_secs()); + } + } mesh_handles } diff --git a/src/vulkan/mesh.rs b/src/vulkan/mesh.rs index 6dd4620..ad72996 100644 --- a/src/vulkan/mesh.rs +++ b/src/vulkan/mesh.rs @@ -1,6 +1,6 @@ use std::time::SystemTime; -use gltf::Error; +use gltf::{Document, Error}; use gltf::mesh::util::{ReadJoints, ReadNormals, ReadPositions, ReadTangents, ReadTexCoords, ReadWeights}; use crate::vulkan::mesh::LoadError::{GltfError, MeshDataMissing, NoIndices}; @@ -34,7 +34,7 @@ pub struct CPUMesh { pub name: Option, } -pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, Vec), LoadError> { +pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, Document), LoadError> { let mut start_time = None; let mut total_vertices = 0; let mut total_indices = 0; @@ -92,7 +92,7 @@ pub fn load_mesh(mesh_path: &str, print_status: bool) -> Result<(Vec, V println!("Finished loading file, total vertices: {}, total indices: {}", total_vertices, total_indices); } - Ok((meshes, textures)) + Ok((meshes, document)) } fn create_vertices(positions: Option, diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 095a060..145c020 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -433,20 +433,11 @@ impl VulkanRenderer { self.game_data.meshes.len() - 1 } - pub fn upload_texture(self: &mut Self, texture_data: &gltf::image::Data, device: Arc) { + pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, device: Arc) { // Format buffer on cpu for upload - let buffer: ImageBuffer, Vec> = image::ImageBuffer::from_raw(texture_data.width, texture_data.height, texture_data.pixels.clone()).unwrap(); - let new_buffer: ImageBuffer, Vec> = buffer.convert(); - let dimensions = Dimensions::Dim2d { width: texture_data.width, height: texture_data.height }; + let dimensions = Dimensions::Dim2d { width, height }; - let source = CpuAccessibleBuffer::from_iter( - self.device.clone(), - BufferUsage::transfer_source(), - false, - new_buffer.iter().cloned(), - ).unwrap(); - - let (image_view, future) = ImmutableImage::from_buffer(source.clone(), dimensions, MipmapsCount::Log2, Format::R8G8B8A8Unorm, self.queue.clone()).unwrap(); + let (image_view, future) = ImmutableImage::from_iter(bytes.iter().cloned(), dimensions, MipmapsCount::One, format, self.queue.clone()).unwrap(); future.flush().unwrap(); let sampler = Sampler::new(device.clone(), Filter::Linear, Filter::Linear,