mip maps (but broken because of vulkano)
This commit is contained in:
@@ -78,7 +78,7 @@ impl Game for TestGame {
|
|||||||
|
|
||||||
// Custom game object stuff
|
// Custom game object stuff
|
||||||
let light_pos = self.player.camera.position * -1.0;
|
let light_pos = self.player.camera.position * -1.0;
|
||||||
self.player.update(frame_time, input, renderer);
|
self.player.update(frame_time, &self.input, renderer);
|
||||||
|
|
||||||
// End frame
|
// End frame
|
||||||
self.last_time = time;
|
self.last_time = time;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::time::SystemTime;
|
|||||||
use cgmath::{Matrix4, SquareMatrix};
|
use cgmath::{Matrix4, SquareMatrix};
|
||||||
use image::{ImageBuffer, ImageFormat, Rgb, Rgba};
|
use image::{ImageBuffer, ImageFormat, Rgb, Rgba};
|
||||||
use image::buffer::ConvertBuffer;
|
use image::buffer::ConvertBuffer;
|
||||||
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
|
use vulkano::{command_buffer::CommandBuffer, buffer::{BufferUsage, CpuAccessibleBuffer}, image::{ImageLayout, MipmapsCount}};
|
||||||
use vulkano::command_buffer::{AutoCommandBuffer, AutoCommandBufferBuilder, DynamicState};
|
use vulkano::command_buffer::{AutoCommandBuffer, AutoCommandBufferBuilder, DynamicState};
|
||||||
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
|
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
|
||||||
use vulkano::descriptor::DescriptorSet;
|
use vulkano::descriptor::DescriptorSet;
|
||||||
@@ -279,7 +279,7 @@ impl VulkanRenderer {
|
|||||||
|
|
||||||
let default_tex = {
|
let default_tex = {
|
||||||
let image = image::load_from_memory_with_format(include_bytes!("../models/missing-texture.jpg"),
|
let image = image::load_from_memory_with_format(include_bytes!("../models/missing-texture.jpg"),
|
||||||
ImageFormat::Jpeg).unwrap().to_rgba();
|
ImageFormat::Jpeg).unwrap().to_rgba8();
|
||||||
let image_data = image.into_raw().clone();
|
let image_data = image.into_raw().clone();
|
||||||
|
|
||||||
let (image_view, future) = ImmutableImage::from_iter(
|
let (image_view, future) = ImmutableImage::from_iter(
|
||||||
@@ -482,17 +482,72 @@ impl VulkanRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn upload_texture(self: &mut Self, texture_data: &gltf::image::Data) {
|
pub fn upload_texture(self: &mut Self, texture_data: &gltf::image::Data) {
|
||||||
|
// Format buffer on cpu for upload
|
||||||
let buffer: ImageBuffer<Rgb<u8>, Vec<u8>> = image::ImageBuffer::from_raw(texture_data.width, texture_data.height, texture_data.pixels.clone()).unwrap();
|
let buffer: ImageBuffer<Rgb<u8>, Vec<u8>> = image::ImageBuffer::from_raw(texture_data.width, texture_data.height, texture_data.pixels.clone()).unwrap();
|
||||||
let new_buffer: ImageBuffer<Rgba<u8>, Vec<u8>> = buffer.convert();
|
let new_buffer: ImageBuffer<Rgba<u8>, Vec<u8>> = buffer.convert();
|
||||||
|
let dimensions = Dimensions::Dim2d { width: texture_data.width, height: texture_data.height };
|
||||||
|
|
||||||
let (image_view, future) = ImmutableImage::from_iter(
|
let source = CpuAccessibleBuffer::from_iter(
|
||||||
|
self.device.clone(),
|
||||||
|
BufferUsage::transfer_source(),
|
||||||
|
false,
|
||||||
new_buffer.iter().cloned(),
|
new_buffer.iter().cloned(),
|
||||||
Dimensions::Dim2d { width: texture_data.width, height: texture_data.height },
|
|
||||||
Format::R8G8B8A8Unorm,
|
|
||||||
self.queue.clone(),
|
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
future.flush().unwrap();
|
// Create image
|
||||||
|
let (image_view, init) = ImmutableImage::uninitialized(
|
||||||
|
self.device.clone(),
|
||||||
|
dimensions,
|
||||||
|
Format::R8G8B8A8Unorm,
|
||||||
|
MipmapsCount::Log2,
|
||||||
|
ImageUsage {
|
||||||
|
transfer_source: true,
|
||||||
|
transfer_destination: true,
|
||||||
|
sampled: true,
|
||||||
|
..ImageUsage::none()
|
||||||
|
},
|
||||||
|
ImageLayout::ShaderReadOnlyOptimal,
|
||||||
|
self.device.active_queue_families()
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
// Upload image data
|
||||||
|
let mut command_buffer_builder = AutoCommandBufferBuilder::new(self.device.clone(), self.queue.family()).unwrap();
|
||||||
|
command_buffer_builder.copy_buffer_to_image_dimensions(
|
||||||
|
source,
|
||||||
|
init,
|
||||||
|
[0, 0, 0],
|
||||||
|
dimensions.width_height_depth(),
|
||||||
|
0,
|
||||||
|
dimensions.array_layers_with_cube(),
|
||||||
|
0,
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
// Generate mipmaps
|
||||||
|
let mut mip_width = image_view.dimensions().width() as i32;
|
||||||
|
let mut mip_height = image_view.dimensions().height() as i32;
|
||||||
|
|
||||||
|
for i in 0..image_view.mipmap_levels() {
|
||||||
|
command_buffer_builder.blit_image(
|
||||||
|
image_view.clone(),
|
||||||
|
[0; 3],
|
||||||
|
[mip_width, mip_height, 1],
|
||||||
|
0,
|
||||||
|
i,
|
||||||
|
image_view.clone(),
|
||||||
|
[0; 3],
|
||||||
|
[mip_width / 2, mip_height / 2, 1],
|
||||||
|
0,
|
||||||
|
i + 1,
|
||||||
|
dimensions.array_layers_with_cube(),
|
||||||
|
Filter::Linear).unwrap();
|
||||||
|
|
||||||
|
if mip_width > 1 { mip_width = mip_width / 2; }
|
||||||
|
if mip_height > 1 { mip_height = mip_height / 2; }
|
||||||
|
}
|
||||||
|
|
||||||
|
let command_buffer = command_buffer_builder.build().unwrap();
|
||||||
|
let command_buffer_future = command_buffer.execute(self.queue.clone()).unwrap();
|
||||||
|
command_buffer_future.flush().unwrap();
|
||||||
|
|
||||||
self.game_data.textures.push(image_view);
|
self.game_data.textures.push(image_view);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user