font i guess?

This commit is contained in:
2021-10-13 21:53:12 +02:00
parent 00d6d1c5f8
commit db9a455311
7 changed files with 228 additions and 94 deletions

View File

@@ -2,9 +2,9 @@ use std::{convert::TryInto, io::Read};
use vulkano::{format::Format, sampler::{Filter, SamplerAddressMode}};
use super::VulkanRenderer;
use super::{Texture, VulkanRenderer};
pub fn upload_texture_from_file(path: &str, renderer: &mut VulkanRenderer) -> Result<(), Box<dyn std::error::Error>> {
pub fn upload_texture_from_file(path: &str, renderer: &mut VulkanRenderer) -> Result<Texture, Box<dyn std::error::Error>> {
// Load file
let mut tex_file = std::fs::File::open(path)?;
let mut tex_bytes: Vec<u8> = vec![];
@@ -24,19 +24,18 @@ pub fn upload_texture_from_file(path: &str, renderer: &mut VulkanRenderer) -> Re
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, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone());
}
if is_dx10
{
let texture = if is_dxt1 {
renderer.upload_texture(&tex_bytes[128..], tex_width, tex_height, Format::BC1_RGBUnormBlock, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone())
} else if is_dx10 {
let dxgi_type = u32::from_ne_bytes(tex_bytes[128..132].try_into()?);
assert!(dxgi_type == 83); // BC5 Unorm Typeless
renderer.upload_texture(&tex_bytes[128+20..], tex_width, tex_height, Format::BC5UnormBlock, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone());
}
renderer.upload_texture(&tex_bytes[128+20..], tex_width, tex_height, Format::BC5UnormBlock, Filter::Linear, SamplerAddressMode::Repeat, renderer.device.clone())
} else {
panic!("Unknown texture type!");
};
Ok(())
Ok(texture)
}
pub fn get_block_size(format: Format) -> Option<u32> {

View File

@@ -11,8 +11,7 @@ use super::pipelines::vs;
#[derive(Clone)]
pub struct GameObject {
pub mesh_index: usize,
pub texture_index: TextureHandle,
pub normal_map_index: TextureHandle,
pub textures: TextureData,
pub position: Vector3<f32>,
pub rotation: Quaternion<f32>,
pub scale: Vector3<f32>,
@@ -22,9 +21,20 @@ pub struct GameObject {
pub pipeline_index: usize,
}
#[derive(Clone)]
pub struct TextureData {
pub texture_index: TextureHandle,
pub normal_map_index: TextureHandle,
}
impl GameObject {
pub fn new(mesh: MeshHandle) -> GameObject {
GameObject { mesh_index: mesh.index, texture_index: mesh.diffuse_handle, normal_map_index: mesh.normal_handle.unwrap_or(0), position: Vector3::new(0.0, 0.0, 0.0),
let textures = TextureData {
texture_index: mesh.diffuse_handle,
normal_map_index: mesh.normal_handle.unwrap_or(0),
};
GameObject { mesh_index: mesh.index, textures, position: Vector3::new(0.0, 0.0, 0.0),
rotation: Quaternion::new(1.0, 0.0, 0.0, 0.0), scale: Vector3::new(1.0, 1.0, 1.0), children: vec![],
descriptor_sets: vec![], is_selected: false, pipeline_index: mesh.pipeline_index }
}

View File

@@ -95,6 +95,7 @@ pub struct MeshHandle {
}
pub(crate) type TextureHandle = usize;
#[derive(Debug, Clone)]
pub struct Texture {
pub image: Arc<ImmutableImage<Format>>,
pub sampler: Arc<Sampler>
@@ -331,7 +332,11 @@ impl VulkanRenderer {
Arc::new(builder.build().unwrap())
}
pub fn update_descriptor_set(&mut self, game_object_handle: &mut GameObjectHandle) {
let pipeline_index = game_object_handle.get_game_object_mut(self).unwrap().pipeline_index;
let textures = game_object_handle.get_game_object_mut(self).unwrap().textures.clone();
self.pipelines[pipeline_index].create_descriptor_set(&textures, self);
}
pub fn render_loop(self: &mut Self, new_ubo: vs::ty::ObjectUniformData) {
// cleanup previous frame
@@ -460,17 +465,16 @@ impl VulkanRenderer {
}
}
pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, filter: Filter, wrap: SamplerAddressMode, device: Arc<Device>) {
pub fn upload_texture(self: &mut Self, bytes: &[u8], width: u32, height: u32, format: Format, filter: Filter, wrap: SamplerAddressMode, device: Arc<Device>) -> Texture {
let dimensions = Dimensions::Dim2d { width, height };
let usage = ImageUsage {
transfer_destination: true,
transfer_source: false,
transfer_source: true,
sampled: true,
..ImageUsage::none()
};
let layout = ImageLayout::ShaderReadOnlyOptimal;
let mip_maps = if format == Format::R8Uint { MipmapsCount::One } else { MipmapsCount::Log2 };
let (image_view, initializer) = ImmutableImage::uninitialized(
@@ -479,7 +483,7 @@ impl VulkanRenderer {
format,
mip_maps,
usage,
layout,
ImageLayout::ShaderReadOnlyOptimal,
device.active_queue_families(),
).unwrap();
@@ -548,11 +552,79 @@ impl VulkanRenderer {
MipmapMode::Linear, wrap, wrap, wrap,
0.0, 1.0, 0.0, (image_view.mipmap_levels() - 1) as f32).unwrap();
self.game_data.textures.push(Texture { image: image_view, sampler });
Texture { image: image_view, sampler }
}
pub fn blit_and_update_texture(&mut self, texture: &Texture, new_data: &[u8], new_data_dimensions: [u32; 3], device: Arc<Device>) -> Texture {
let new_image_usage = ImageUsage {
transfer_destination: true,
transfer_source: true,
sampled: true,
..ImageUsage::none()
};
let (new_image_view, new_image_initializer) = ImmutableImage::uninitialized(
device.clone(),
Dimensions::Dim2d { width: texture.image.dimensions().width(), height: texture.image.dimensions().height() },
texture.image.format(),
texture.image.mipmap_levels(),
new_image_usage,
ImageLayout::ShaderReadOnlyOptimal,
device.active_queue_families(),
).unwrap();
let new_sub_image = SubImage::new(
Arc::new(new_image_initializer),
0,
new_image_view.mipmap_levels(),
0,
1,
ImageLayout::ShaderReadOnlyOptimal,
);
let mut cbb = AutoCommandBufferBuilder::new(device.clone(), self.queue.family()).unwrap();
// cbb.copy_image(
// texture.image.clone(),
// [0, 0, 0],
// 0,
// 0,
// new_sub_image.clone(),
// [0, 0, 0],
// 0,
// 0,
// texture.image.dimensions().width_height_depth(),
// 1
// ).unwrap();
let upload_source = CpuAccessibleBuffer::from_iter(
device.clone(),
BufferUsage::transfer_source(),
false,
new_data.iter().cloned(),
).unwrap();
cbb.copy_buffer_to_image_dimensions(
upload_source.clone(),
new_sub_image.clone(),
[0, 0, 0],
new_data_dimensions,
0,
1,
0,
).unwrap();
let cb = cbb.build().unwrap();
let future = cb.execute(self.queue.clone()).unwrap();
future.flush().unwrap();
Texture { image: new_image_view, sampler: texture.sampler.clone() }
}
pub fn add_game_object(self: &mut Self, mut game_object: GameObject) -> GameObjectHandle {
self.pipelines[game_object.pipeline_index].create_descriptor_set(&mut game_object, self);
game_object.descriptor_sets = self.pipelines[game_object.pipeline_index].create_descriptor_set(&game_object.textures, self);
self.game_data.game_objects.push(game_object);
GameObjectHandle {

View File

@@ -1,6 +1,6 @@
use std::{convert::TryInto, io::{self, ErrorKind, Read, Write}, path::PathBuf, sync::Arc};
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::{shader::{ShaderModule}}};
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{DescriptorSet, descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::{shader::{ShaderModule}}};
use vulkano::command_buffer::DynamicState;
use vulkano::device::Device;
use vulkano::framebuffer::RenderPassAbstract;
@@ -14,12 +14,15 @@ use crate::vulkan::{LinePoint, Vertex};
use crate::vulkan::GameData;
use crate::VulkanRenderer;
use super::gameobject::TextureData;
type RP = Arc<dyn RenderPassAbstract + Send + Sync>;
type GP = Arc<dyn GraphicsPipelineAbstract + Send + Sync>;
type DS = Arc<dyn DescriptorSet + Send + Sync>;
pub trait Drawcall {
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState);
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer);
fn create_descriptor_set(self: &Self, textures: &TextureData, renderer: &VulkanRenderer) -> Vec<DS>;
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP);
fn get_pipeline(self: &Self) -> &GP;
}
@@ -152,17 +155,17 @@ impl Drawcall for DefaultShader {
}
}
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer) {
fn create_descriptor_set(self: &Self, textures: &TextureData, renderer: &VulkanRenderer) -> Vec<DS> {
let descriptor_set_layout = self.get_pipeline().descriptor_set_layout(0).unwrap().clone();
println!("Diff: {:?}, Norm: {:?}", game_object.texture_index, game_object.normal_map_index);
println!("Diff: {:?}, Norm: {:?}", textures.texture_index, textures.normal_map_index);
game_object.descriptor_sets = renderer.uniform_buffers.iter().map(|uniform_buffer| {
renderer.uniform_buffers.iter().map(|uniform_buffer| {
let descriptor_set: Arc<(dyn vulkano::descriptor::DescriptorSet + std::marker::Send + std::marker::Sync + 'static)>;
let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone());
let diffuse = &renderer.game_data.textures[game_object.texture_index];
let normal_map = &renderer.game_data.textures[game_object.normal_map_index];
let diffuse = &renderer.game_data.textures[textures.texture_index];
let normal_map = &renderer.game_data.textures[textures.normal_map_index];
descriptor_set = Arc::new(builder
.add_buffer(uniform_buffer.clone()).unwrap()
@@ -171,7 +174,7 @@ impl Drawcall for DefaultShader {
.build().unwrap());
descriptor_set
}).collect();
}).collect()
}
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP) {
@@ -238,8 +241,8 @@ impl Drawcall for LineShader {
game_data.line_push_constants.clone()).unwrap();
}
fn create_descriptor_set(self: &Self, _game_object: &mut GameObject, _renderer: &VulkanRenderer) {
fn create_descriptor_set(self: &Self, _textures: &TextureData, _renderer: &VulkanRenderer) -> Vec<DS> {
vec![]
}
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP) {
@@ -339,14 +342,14 @@ impl Drawcall for TextShader {
}
}
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer) {
fn create_descriptor_set(self: &Self, textures: &TextureData, renderer: &VulkanRenderer) -> Vec<DS> {
let descriptor_set_layout = self.get_pipeline().descriptor_set_layout(0).unwrap().clone();
game_object.descriptor_sets = renderer.uniform_buffers.iter().map(|uniform_buffer| {
renderer.uniform_buffers.iter().map(|uniform_buffer| {
let descriptor_set: Arc<(dyn vulkano::descriptor::DescriptorSet + std::marker::Send + std::marker::Sync + 'static)>;
let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone());
let diffuse = &renderer.game_data.textures[game_object.texture_index];
let diffuse = &renderer.game_data.textures[textures.texture_index];
descriptor_set = Arc::new(builder
.add_buffer(uniform_buffer.clone()).unwrap()
@@ -355,7 +358,7 @@ impl Drawcall for TextShader {
.build().unwrap());
descriptor_set
}).collect();
}).collect()
}
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP) {