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

@@ -21,7 +21,7 @@ layout(location = 3) in mat3 tbn;
layout(location = 0) out vec4 out_color; layout(location = 0) out vec4 out_color;
void main() { 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 = normal_cam_u * 2.0 - 1.0;
normal_cam_u = normalize(tbn * normal_cam_u); normal_cam_u = normalize(tbn * normal_cam_u);

Binary file not shown.

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 cgmath::{Deg, InnerSpace, Quaternion, Rotation3};
use winit::event::Event; use winit::event::Event;
@@ -7,7 +7,7 @@ use winit::event::Event;
use level::{load_level, save_level}; use level::{load_level, save_level};
use player::Player; use player::Player;
use crate::config::LogConfig; use crate::{config::LogConfig, vulkan};
use crate::input::InputState; use crate::input::InputState;
use crate::vulkan::{Game, MeshHandle, VulkanRenderer}; use crate::vulkan::{Game, MeshHandle, VulkanRenderer};
use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable}; use crate::vulkan::gameobject::{GameObject, GameObjectHandle, Updatable};
@@ -149,24 +149,7 @@ impl TestGame {
{ {
let texture_start_time = SystemTime::now(); let texture_start_time = SystemTime::now();
// Load file vulkan::dds::upload_texture_from_file(&format!("models/textures/{}.dds", doc_image.name().unwrap()), renderer).unwrap();
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());
self.texture_index_counter += 1; self.texture_index_counter += 1;
if self.log_config.mesh_load_info { 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 pipelines;
pub mod gameobject; pub mod gameobject;
pub mod mesh; pub mod mesh;
pub mod dds;
mod renderpass; mod renderpass;
mod framebuffers; mod framebuffers;
@@ -464,12 +465,17 @@ impl VulkanRenderer {
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap(); 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() { for i in 0..image_view.mipmap_levels() {
let mip_size = dimensions.to_image_dimensions().mipmap_dimensions(i).unwrap().width_height_depth(); let mip_size = dimensions.to_image_dimensions().mipmap_dimensions(i).unwrap().width_height_depth();
let block_bytes = 8;
let mip_byte_size = ( let mip_byte_size = (
(u32::max(4, mip_size[0]) / 4) (u32::max(4, mip_size[0]) / 4)
* (u32::max(4, mip_size[1]) / 4) * (u32::max(4, mip_size[1]) / 4)