ajout mesh.rs
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
La nouvelle vision architecturale
|
||||||
|
Pour comprendre ce changement, imagine que tu veux peindre 10 tableaux différents.
|
||||||
|
|
||||||
|
Avant (Ton code actuel) : Chaque tableau possède sa propre cuisine, son propre chef (le pipeline), et son propre matériel de peinture. C'est inefficace.
|
||||||
|
|
||||||
|
Après (La nouvelle structure) : Tu as un Atelier (le Renderer) qui contient des Recettes (le Material / Shader) et tu apportes tes Toiles (le Mesh). Tu peux utiliser la même recette pour 50 toiles différentes sans effort.
|
||||||
|
|
||||||
|
Voici la nouvelle répartition des responsabilités :
|
||||||
|
|
||||||
|
1. Le Mesh (La géométrie)
|
||||||
|
Il ne sait pas comment il est affiché, il sait seulement ce qu'il est.
|
||||||
|
|
||||||
|
Contenu : Il possède les données brutes (le VertexBuffer et éventuellement un IndexBuffer pour optimiser le dessin).
|
||||||
|
|
||||||
|
Rôle : Il est passif. C'est juste un conteneur de données prêtes à être envoyées à la carte graphique.
|
||||||
|
|
||||||
|
2. Le Material (Le look)
|
||||||
|
Il définit l'apparence de l'objet.
|
||||||
|
|
||||||
|
Contenu : Il possède le RenderPipeline. Le pipeline contient tout ce qui est "lourd" à créer (le shader compilé, les états de fusion, le mode de tracé).
|
||||||
|
|
||||||
|
Rôle : Il est réutilisable. Si tu as 10 objets en métal, ils partagent tous le même Material (donc le même pipeline).
|
||||||
|
|
||||||
|
3. Le Renderer (L'Orchestrateur)
|
||||||
|
Il devient beaucoup plus léger et efficace.
|
||||||
|
|
||||||
|
Contenu : Il ne possède plus de buffers en dur. Il possède une méthode render qui accepte un Mesh ET un Material.
|
||||||
|
|
||||||
|
Rôle : Il fait la liaison au moment de l'appel :
|
||||||
|
|
||||||
|
Rust
|
||||||
|
// Schématiquement
|
||||||
|
renderer.render_pass.set_pipeline(&material.pipeline); // On change de recette
|
||||||
|
renderer.render_pass.set_vertex_buffer(0, &mesh.buffer); // On pose la toile
|
||||||
|
renderer.render_pass.draw(...);
|
||||||
|
Pourquoi cette structure est-elle meilleure ?
|
||||||
|
Réutilisation (Performance) : Si tu as 100 objets avec le même shader, tu ne compiles ton shader qu'une seule fois. Tu gagnes énormément en vitesse de chargement et en occupation mémoire.
|
||||||
|
|
||||||
|
Modularité : Tu peux créer un Mesh "Cercle" et un Mesh "Carré". Tu peux créer un Material "Rouge" et un Material "Bleu". Tu peux combiner n'importe quel Mesh avec n'importe quel Material sans changer une ligne de code.
|
||||||
|
|
||||||
|
Nettoyage : Ton renderer.rs devient un orchestrateur pur au lieu d'être un fourre-tout.
|
||||||
|
|
||||||
|
La note technique : "Pipeline Cache"
|
||||||
|
Dans cette nouvelle structure, tu devras faire attention à un détail : le couplage entre le Mesh et le Material.
|
||||||
|
Si ton Mesh a une structure de Vertex différente de ce que le Material (Shader) attend, le rendu sera invalide. Le Material doit donc garantir qu'il est capable de traiter le format de données fourni par le Mesh.
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
pub mod conf;
|
pub mod conf;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
pub mod mesh;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
pub mod vertex;
|
pub mod vertex;
|
||||||
|
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
use crate::vertex::Vertex;
|
||||||
|
use wgpu::util::DeviceExt;
|
||||||
|
|
||||||
|
pub struct Mesh {
|
||||||
|
pub vertex_buffer: wgpu::Buffer,
|
||||||
|
pub index_buffer: Option<wgpu::Buffer>,
|
||||||
|
pub num_vertices: u32,
|
||||||
|
pub num_indices: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mesh {
|
||||||
|
pub fn new(device: &wgpu::Device, vertices: &[Vertex], indices: Option<&[u16]>) -> Self {
|
||||||
|
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Mesh Vertex Buffer"),
|
||||||
|
contents: bytemuck::cast_slice(vertices),
|
||||||
|
usage: wgpu::BufferUsages::VERTEX,
|
||||||
|
});
|
||||||
|
|
||||||
|
let (index_buffer, num_indices) = if let Some(data) = indices {
|
||||||
|
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Mesh Index Buffer"),
|
||||||
|
usage: wgpu::BufferUsages::INDEX,
|
||||||
|
contents: bytemuck::cast_slice(data),
|
||||||
|
});
|
||||||
|
(Some(buffer), data.len() as u32)
|
||||||
|
} else {
|
||||||
|
(None, 0)
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
vertex_buffer,
|
||||||
|
index_buffer,
|
||||||
|
num_vertices: vertices.len() as u32,
|
||||||
|
num_indices,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user