Refactor texture loading

This commit is contained in:
Florian RICHER 2025-06-08 18:38:51 +02:00
parent f91c0792b2
commit a32cf6c747
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
19 changed files with 1499 additions and 337 deletions

View file

@ -4,19 +4,22 @@ use super::settings_scene::SettingsScene;
use crate::core::app::DEPTH_IMAGE_ID;
use crate::core::app::context::WindowContext;
use crate::core::app::user_event::UserEvent;
use crate::core::render::primitives::AsRecordable;
use crate::core::render::primitives::camera::Camera3D;
use crate::core::render::primitives::mvp::Mvp;
use crate::core::render::primitives::transform::Transform;
use crate::core::render::primitives::{AsBindableDescriptorSet, AsRecordable};
use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager};
use crate::core::render::texture::Texture;
use crate::core::render::resources::meshes::{ObjMesh, SquareMesh};
use crate::core::render::resources::texture::{
Texture, TextureLoadInfo, TextureLoader, TextureSourceKind,
};
use crate::core::scene::Scene;
use crate::game::assets::meshs::square::Square;
use crate::game::assets::pipelines::simple::{SimplePipeline, SimplePipelineRenderData};
use egui_winit_vulkano::egui;
use glam::EulerRot;
use glam::Quat;
use glam::Vec3;
use vulkano::format::Format;
use vulkano::image::sampler::{Filter, SamplerAddressMode, SamplerCreateInfo};
use vulkano::{
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract},
sync::GpuFuture,
@ -24,11 +27,13 @@ use vulkano::{
use winit::window::CursorGrabMode;
pub struct MainSceneState {
square: Square,
texture_loader: TextureLoader,
square: SquareMesh,
obj: ObjMesh,
simple_pipeline: SimplePipeline,
instances: Vec<Transform>,
square_instances: Vec<Transform>,
obj_instances: Vec<Transform>,
camera: Camera3D,
texture: Texture,
speed: f32,
}
@ -50,7 +55,41 @@ impl Scene for MainScene {
let swapchain_image_view =
app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone());
let square = Square::new(&app_context.memory_allocator)?;
let mut texture_loader = TextureLoader::new(app_context);
texture_loader.add_texture(
"wooden-crate".to_string(),
TextureLoadInfo {
source: TextureSourceKind::File("res/textures/wooden-crate.jpg".to_string()),
sampler_create_info: SamplerCreateInfo {
mag_filter: Filter::Linear,
min_filter: Filter::Linear,
address_mode: [SamplerAddressMode::Repeat; 3],
..Default::default()
},
image_format: Format::R8G8B8A8_SRGB,
},
);
texture_loader.add_texture(
"cube-diffuse".to_string(),
TextureLoadInfo {
source: TextureSourceKind::File("res/objects/cube-diffuse.jpg".to_string()),
sampler_create_info: SamplerCreateInfo {
mag_filter: Filter::Linear,
min_filter: Filter::Linear,
address_mode: [SamplerAddressMode::Repeat; 3],
..Default::default()
},
image_format: Format::R8G8B8A8_SRGB,
},
);
texture_loader.load_pending_textures()?;
let square = SquareMesh::new(&app_context.memory_allocator)?;
let obj = {
let obj = ObjMesh::new(&app_context.memory_allocator, "res/objects/cube.obj")?;
obj.into_iter().next().unwrap()
};
let simple_pipeline = SimplePipeline::new(
&app_context.device,
swapchain_image_view.format(),
@ -61,7 +100,7 @@ impl Scene for MainScene {
let instance_size = 10.0;
let instance_spacing = 10.0;
let num_instances_per_row = (num_instances as f32 / instance_spacing).ceil() as u32;
let instances: Vec<Transform> = (0..num_instances)
let square_instances: Vec<Transform> = (0..num_instances)
.map(|i| {
Transform::new(
Vec3::new(
@ -75,26 +114,26 @@ impl Scene for MainScene {
})
.collect();
let texture = {
let mut uploads = AutoCommandBufferBuilder::primary(
app_context.command_buffer_allocator.clone(),
app_context.graphics_queue.queue_family_index(),
CommandBufferUsage::OneTimeSubmit,
)?;
let texture = Texture::from_file(
&app_context.device,
&app_context.memory_allocator,
&mut uploads,
"res/textures/wooden-crate.jpg",
)?;
let _ = uploads
.build()?
.execute(app_context.graphics_queue.clone())?;
texture
};
let obj_instances: Vec<Transform> = (0..num_instances)
.map(|i| {
Transform::new(
Vec3::new(
(i % num_instances_per_row) as f32 * (instance_spacing + instance_size),
0.0,
(i / num_instances_per_row) as f32
* (instance_spacing + instance_size)
* -1.0
- instance_spacing * 2.0,
),
Quat::from_euler(EulerRot::XYZ, 0.0, rand::random_range(0.0..=360.0), 0.0),
Vec3::new(
instance_size * 0.5,
instance_size * 0.5,
instance_size * 0.5,
),
)
})
.collect();
let camera = app_context.with_renderer(|renderer| {
Camera3D::new(
@ -107,11 +146,13 @@ impl Scene for MainScene {
self.state = Some(MainSceneState {
square,
obj,
simple_pipeline,
instances,
square_instances,
obj_instances,
camera,
texture,
speed: 50.0,
texture_loader,
});
Ok(())
@ -132,7 +173,14 @@ impl Scene for MainScene {
});
let delta_time = app_context.get_delta_time();
for (i, instance) in state.instances.iter_mut().enumerate() {
for (i, instance) in state.square_instances.iter_mut().enumerate() {
let rotation_speed = (i % 10) as f32;
let rotation_delta = Quat::from_rotation_y(rotation_speed * delta_time);
instance.rotate(rotation_delta);
}
for (i, instance) in state.obj_instances.iter_mut().enumerate() {
let rotation_speed = (i % 10) as f32;
let rotation_delta = Quat::from_rotation_y(rotation_speed * delta_time);
@ -203,21 +251,40 @@ impl Scene for MainScene {
// Create camera uniform using the actual camera
let camera_uniform = state.camera.create_buffer(&app_context.memory_allocator)?;
let transform_uniform =
Transform::create_buffer(&app_context.memory_allocator, &state.instances)?;
let square_transform_uniform =
Transform::create_buffer(&app_context.memory_allocator, &state.square_instances)?;
let obj_transform_uniform =
Transform::create_buffer(&app_context.memory_allocator, &state.obj_instances)?;
SimplePipeline::record_bind_commands(
&mut builder,
&app_context.descriptor_set_allocator,
state.simple_pipeline.pipeline(),
&state.square,
&transform_uniform,
&square_transform_uniform,
&SimplePipelineRenderData {
mvp_uniform: &camera_uniform,
texture: &state.texture,
texture: &state.texture_loader.get_texture("wooden-crate").unwrap(),
},
)?;
SimplePipeline::record_draw_commands(&mut builder, &state.square, &transform_uniform)?;
SimplePipeline::record_draw_commands(
&mut builder,
&state.square,
&square_transform_uniform,
)?;
SimplePipeline::record_bind_commands(
&mut builder,
&app_context.descriptor_set_allocator,
state.simple_pipeline.pipeline(),
&state.obj,
&obj_transform_uniform,
&SimplePipelineRenderData {
mvp_uniform: &camera_uniform,
texture: &state.texture_loader.get_texture("cube-diffuse").unwrap(),
},
)?;
SimplePipeline::record_draw_commands(&mut builder, &state.obj, &obj_transform_uniform)?;
RenderPassManager::end_rendering(&mut builder)?;