three_d/renderer/geometry/
sprites.rs1use crate::core::*;
2use crate::renderer::*;
3
4pub struct Sprites {
12 context: Context,
13 position_buffer: VertexBuffer<Vec3>,
14 uv_buffer: VertexBuffer<Vec2>,
15 center_buffer: InstanceBuffer<Vec3>,
16 transformation: Mat4,
17 direction: Option<Vec3>,
18}
19
20impl Sprites {
21 pub fn new(context: &Context, centers: &[Vec3], direction: Option<Vec3>) -> Self {
26 let position_buffer = VertexBuffer::new_with_data(
27 context,
28 &[
29 vec3(-1.0, -1.0, 0.0),
30 vec3(1.0, -1.0, 0.0),
31 vec3(1.0, 1.0, 0.0),
32 vec3(1.0, 1.0, 0.0),
33 vec3(-1.0, 1.0, 0.0),
34 vec3(-1.0, -1.0, 0.0),
35 ],
36 );
37 let uv_buffer = VertexBuffer::new_with_data(
38 context,
39 &[
40 vec2(0.0, 0.0),
41 vec2(1.0, 0.0),
42 vec2(1.0, 1.0),
43 vec2(1.0, 1.0),
44 vec2(0.0, 1.0),
45 vec2(0.0, 0.0),
46 ],
47 );
48 Self {
49 context: context.clone(),
50 position_buffer,
51 uv_buffer,
52 center_buffer: InstanceBuffer::new_with_data(context, centers),
53 transformation: Mat4::identity(),
54 direction,
55 }
56 }
57
58 pub fn transformation(&self) -> Mat4 {
62 self.transformation
63 }
64
65 pub fn set_transformation(&mut self, transformation: Mat4) {
69 self.transformation = transformation;
70 }
71
72 pub fn set_direction(&mut self, direction: Option<Vec3>) {
76 self.direction = direction;
77 }
78
79 pub fn set_centers(&mut self, centers: &[Vec3]) {
83 self.center_buffer.fill(centers);
84 }
85
86 fn draw(&self, program: &Program, render_states: RenderStates, viewer: &dyn Viewer) {
87 program.use_uniform("eye", viewer.position());
88 program.use_uniform("viewProjection", viewer.projection() * viewer.view());
89 program.use_uniform("transformation", self.transformation);
90 program.use_vertex_attribute("position", &self.position_buffer);
91 if program.requires_attribute("uv_coordinate") {
92 program.use_vertex_attribute("uv_coordinate", &self.uv_buffer);
93 }
94 program.use_instance_attribute("center", &self.center_buffer);
95 program.use_uniform("direction", self.direction.unwrap_or(vec3(0.0, 0.0, 0.0)));
96 program.draw_arrays_instanced(
97 render_states,
98 viewer.viewport(),
99 6,
100 self.center_buffer.instance_count(),
101 )
102 }
103}
104
105impl<'a> IntoIterator for &'a Sprites {
106 type Item = &'a dyn Geometry;
107 type IntoIter = std::iter::Once<&'a dyn Geometry>;
108
109 fn into_iter(self) -> Self::IntoIter {
110 std::iter::once(self)
111 }
112}
113
114impl Geometry for Sprites {
115 fn draw(&self, viewer: &dyn Viewer, program: &Program, render_states: RenderStates) {
116 self.draw(program, render_states, viewer);
117 }
118
119 fn vertex_shader_source(&self) -> String {
120 include_str!("shaders/sprites.vert").to_owned()
121 }
122
123 fn id(&self) -> GeometryId {
124 GeometryId::Sprites
125 }
126
127 fn render_with_material(
128 &self,
129 material: &dyn Material,
130 viewer: &dyn Viewer,
131 lights: &[&dyn Light],
132 ) {
133 render_with_material(&self.context, viewer, &self, material, lights);
134 }
135
136 fn render_with_effect(
137 &self,
138 material: &dyn Effect,
139 viewer: &dyn Viewer,
140 lights: &[&dyn Light],
141 color_texture: Option<ColorTexture>,
142 depth_texture: Option<DepthTexture>,
143 ) {
144 render_with_effect(
145 &self.context,
146 viewer,
147 self,
148 material,
149 lights,
150 color_texture,
151 depth_texture,
152 )
153 }
154
155 fn aabb(&self) -> AxisAlignedBoundingBox {
156 AxisAlignedBoundingBox::INFINITE
157 }
158}