veloren_voxygen/render/
model.rs

1use super::{
2    Vertex,
3    buffer::{Buffer, DynamicBuffer},
4    mesh::Mesh,
5};
6use std::ops::Range;
7
8/// Represents a mesh that has been sent to the GPU.
9pub struct SubModel<'a, V: Vertex> {
10    pub vertex_range: Range<u32>,
11    buf: &'a wgpu::Buffer,
12    phantom_data: std::marker::PhantomData<V>,
13}
14
15impl<'a, V: Vertex> SubModel<'a, V> {
16    pub(super) fn buf(&self) -> wgpu::BufferSlice<'a> {
17        let start = self.vertex_range.start as wgpu::BufferAddress * V::STRIDE;
18        let end = self.vertex_range.end as wgpu::BufferAddress * V::STRIDE;
19        self.buf.slice(start..end)
20    }
21
22    #[expect(clippy::len_without_is_empty)]
23    pub fn len(&self) -> u32 { self.vertex_range.end - self.vertex_range.start }
24}
25
26/// Represents a mesh that has been sent to the GPU.
27pub struct Model<V: Vertex> {
28    vbuf: Buffer<V>,
29}
30
31impl<V: Vertex> Model<V> {
32    /// Returns None if the provided mesh is empty
33    pub fn new(device: &wgpu::Device, mesh: &Mesh<V>) -> Option<Self> {
34        if mesh.vertices().is_empty() {
35            return None;
36        }
37
38        Some(Self {
39            vbuf: Buffer::new(device, wgpu::BufferUsages::VERTEX, mesh.vertices()),
40        })
41    }
42
43    /// Create a model with a slice of a portion of this model to send to the
44    /// renderer.
45    pub fn submodel(&self, vertex_range: Range<u32>) -> SubModel<V> {
46        SubModel {
47            vertex_range,
48            buf: self.buf(),
49            phantom_data: std::marker::PhantomData,
50        }
51    }
52
53    pub(super) fn buf(&self) -> &wgpu::Buffer { &self.vbuf.buf }
54
55    #[expect(clippy::len_without_is_empty)]
56    pub fn len(&self) -> usize { self.vbuf.len() }
57}
58
59/// Represents a mesh that has been sent to the GPU.
60pub struct DynamicModel<V: Vertex> {
61    vbuf: DynamicBuffer<V>,
62}
63
64impl<V: Vertex> DynamicModel<V> {
65    pub fn new(device: &wgpu::Device, size: usize) -> Self {
66        Self {
67            vbuf: DynamicBuffer::new(device, size, wgpu::BufferUsages::VERTEX),
68        }
69    }
70
71    pub fn update(&self, queue: &wgpu::Queue, mesh: &Mesh<V>, offset: usize) {
72        self.vbuf.update(queue, mesh.vertices(), offset)
73    }
74
75    /// Create a model with a slice of a portion of this model to send to the
76    /// renderer.
77    pub fn submodel(&self, vertex_range: Range<u32>) -> SubModel<V> {
78        SubModel {
79            vertex_range,
80            buf: self.buf(),
81            phantom_data: std::marker::PhantomData,
82        }
83    }
84
85    pub fn buf(&self) -> &wgpu::Buffer { &self.vbuf.buf }
86
87    #[expect(clippy::len_without_is_empty)]
88    pub fn len(&self) -> usize { self.vbuf.len() }
89}