bc5 normal maps

This commit is contained in:
2021-03-14 16:22:11 +01:00
parent 0c8d09effa
commit c2e3c4e0e4
6 changed files with 52 additions and 23 deletions

View File

@@ -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<u8> = 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 {

40
src/vulkan/dds.rs Normal file
View File

@@ -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<dyn std::error::Error>> {
// Load file
let mut tex_file = std::fs::File::open(path)?;
let mut tex_bytes: Vec<u8> = 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(())
}

View File

@@ -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)