diff --git a/models/textures/cobblestone_large_01_nor_4k.dds b/models/textures/cobblestone_large_01_nor_4k.dds index 1623d4f..362abe8 100644 Binary files a/models/textures/cobblestone_large_01_nor_4k.dds and b/models/textures/cobblestone_large_01_nor_4k.dds differ diff --git a/shaders/triangle.frag b/shaders/triangle.frag index 34a17d2..125097a 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -21,7 +21,7 @@ layout(location = 3) in mat3 tbn; layout(location = 0) out vec4 out_color; void main() { - vec3 normal_cam_u = texture(normal_tex, tex_coords).rgb; + vec3 normal_cam_u = vec3(texture(normal_tex, tex_coords).rg, 1.0); normal_cam_u = normal_cam_u * 2.0 - 1.0; normal_cam_u = normalize(tbn * normal_cam_u); diff --git a/shaders/triangle.frag.spv b/shaders/triangle.frag.spv index cc27aae..17b63a4 100644 Binary files a/shaders/triangle.frag.spv and b/shaders/triangle.frag.spv differ diff --git a/src/game/mod.rs b/src/game/mod.rs index 85e7533..78ef8f5 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -1,5 +1,5 @@ -use std::{convert::TryInto, io::Read, time::SystemTime}; +use std::time::SystemTime; use cgmath::{Deg, InnerSpace, Quaternion, Rotation3}; use winit::event::Event; @@ -7,7 +7,7 @@ use winit::event::Event; use level::{load_level, save_level}; use player::Player; -use crate::config::LogConfig; +use crate::{config::LogConfig, vulkan}; use crate::input::InputState; use crate::vulkan::{Game, MeshHandle, VulkanRenderer}; use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable}; @@ -149,24 +149,7 @@ impl TestGame { { 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); - - renderer.upload_texture(&tex_bytes, tex_width, tex_height, vulkano::format::Format::BC1_RGBUnormBlock, renderer.device.clone()); + vulkan::dds::upload_texture_from_file(&format!("models/textures/{}.dds", doc_image.name().unwrap()), renderer).unwrap(); self.texture_index_counter += 1; if self.log_config.mesh_load_info { diff --git a/src/vulkan/dds.rs b/src/vulkan/dds.rs new file mode 100644 index 0000000..c818571 --- /dev/null +++ b/src/vulkan/dds.rs @@ -0,0 +1,40 @@ +use std::{convert::TryInto, io::Read}; + +use vulkano::format::Format; + +use super::VulkanRenderer; + +pub fn upload_texture_from_file(path: &str, renderer: &mut VulkanRenderer) -> Result<(), Box> { + // Load file + let mut tex_file = std::fs::File::open(path)?; + let mut tex_bytes: Vec = vec![]; + tex_file.read_to_end(&mut tex_bytes)?; + + // Parse DDS + let tex_height = u32::from_ne_bytes(tex_bytes[12..16].try_into()?); + let tex_width = u32::from_ne_bytes(tex_bytes[16..20].try_into()?); + let tex_byte_count = u32::from_ne_bytes(tex_bytes[20..24].try_into()?); + let pixel_format_flags = u32::from_ne_bytes(tex_bytes[80..84].try_into()?); + let pixel_format_name: [u8; 4] = tex_bytes[84..88].try_into()?; + let is_dxt1 = pixel_format_name == [0x44, 0x58, 0x54, 0x31]; // [D,X,T,1] + let is_dx10 = pixel_format_name == [0x44, 0x58, 0x31, 0x30]; // [D,X,1,0] + + assert!(pixel_format_flags == 0x00000004); + assert!(is_dxt1 || is_dx10); + + println!("Texture width: {}, height: {}, bytes: {}", tex_width, tex_height, tex_byte_count); + + if is_dxt1 + { + renderer.upload_texture(&tex_bytes[128..], tex_width, tex_height, Format::BC1_RGBUnormBlock, renderer.device.clone()); + } + if is_dx10 + { + let dxgi_type = u32::from_ne_bytes(tex_bytes[128..132].try_into()?); + assert!(dxgi_type == 83); + + renderer.upload_texture(&tex_bytes[128+20..], tex_width, tex_height, Format::BC5UnormBlock, renderer.device.clone()); + } + + Ok(()) +} \ No newline at end of file diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs index 198f8b0..7af8ca4 100644 --- a/src/vulkan/mod.rs +++ b/src/vulkan/mod.rs @@ -34,6 +34,7 @@ use crate::vulkan::gameobject::{GameObject, GameObjectHandle}; pub mod pipelines; pub mod gameobject; pub mod mesh; +pub mod dds; mod renderpass; mod framebuffers; @@ -464,12 +465,17 @@ impl VulkanRenderer { let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap(); - let mut offset: usize = 128; + let mut offset = 0; + + let block_bytes = match format { + Format::BC1_RGBUnormBlock => 8, + Format::BC5UnormBlock => 16, + f => panic!(format!("Unknown texture format {:?}!", f)) + }; for i in 0..image_view.mipmap_levels() { let mip_size = dimensions.to_image_dimensions().mipmap_dimensions(i).unwrap().width_height_depth(); - let block_bytes = 8; let mip_byte_size = ( (u32::max(4, mip_size[0]) / 4) * (u32::max(4, mip_size[1]) / 4)