cafe/render/
render2D.rs

1extern crate tea;
2extern crate stb_image;
3
4use crate::render::{Image, Canvas, Drawable, Batch, Buffer, Movement};
5
6use tea::vertex::{VertexArray, VertexData, VertexFormatBuilder, VertexFormat};
7use tea::{glsl::*, EnableFlags};
8use tea::texture::{Texture2D, PixelFormat, Sampler2D};
9use tea::target::Framebuffer;
10use tea::impl_vertexdata;
11use tea::vec::*;
12use tea::{GlBind, GlUniform, GlObject, GlTarget, GlUse, DrawMode, BlendFunc};
13use tea::buffer::{ArrayBuffer, ElementArrayBuffer, GlBuffer, BufferUsage};
14use crate::render::{Effect, Render, Camera};
15use crate::{Rect, Color};
16
17
18impl_vertexdata!(Vertex2D, Vec2, Vec4, Vec2);
19
20type Index = (i32, i32, i32, i32, i32, i32);
21
22pub type VertexBuffer = Buffer<ArrayBuffer, Vertex2D>;
23pub type IndexBuffer = Buffer<ElementArrayBuffer, Index>;
24
25impl VertexBuffer {
26    pub fn new(size: usize) -> Result<Self, String> {
27        let handle = ArrayBuffer::new();
28        let data: Vec<Vertex2D> = Vec::with_capacity(size);
29        handle.bind();
30        handle.data(&data, BufferUsage::DynamicDraw);
31        handle.unbind();
32        Ok(Self {
33            handle,
34            data
35        })
36    }
37}
38
39impl IndexBuffer {
40    pub fn new(size: usize) -> Result<Self, String> {
41        let handle = ElementArrayBuffer::new();
42        let mut data: Vec<Index> = Vec::with_capacity(size);
43        for i in 0..(size as i32) {
44            let index = (i, i+1, i+2, i+3, i+1, i);
45            data.push(index);
46        }
47        handle.bind();
48        handle.data(&data, BufferUsage::StaticDraw);
49        handle.unbind();
50        Ok(Self {
51            handle,
52            data
53        })
54    }
55}
56
57#[derive(Default, Debug, PartialEq, Copy, Clone)]
58pub struct Camera2D {
59    position: Vec3,
60    right: Vec3,
61    width: f32, height: f32,
62    near: f32, far: f32,
63    move_speed: f32,
64
65    zoom: f32
66}
67
68impl Camera for Camera2D {
69    fn position(&self) -> &Vec3 { &self.position }
70    fn set_position(&mut self, position: Vec3) { self.position = position; }
71
72    fn set_width(&mut self, width: f32) { self.width = width; }
73    fn set_height(&mut self, height: f32) { self.height = height; }
74
75    fn projection(&self) -> Mat4 {
76        Mat4::ortho(0.0, self.width, self.height, 0.0, self.near, self.far)
77    }
78    
79    fn view(&self) -> Mat4 {
80        Mat4::identity()
81    }
82
83    fn move_camera(&mut self, dir: Movement, dt: f32) {
84        let velocity = self.move_speed * dt;
85        match dir {
86            Movement::Right => { self.position += self.right.scalar(velocity); },
87            Movement::Left => { self.position -= self.right.scalar(velocity); },
88            _ => {}
89        }
90    }
91}
92
93impl Camera2D {
94    pub fn new(width: f32, height: f32) -> Self {
95        let position = Vec3::zero();
96        let right = Vec3::new(1.0, 0.0, 0.0);
97        let near = -0.1;
98        let far = 0.1;
99        let move_speed = 60.0;
100        let zoom = 1.0;
101
102        Self {
103            position,
104            right,
105            width, height,
106            near, far,
107            move_speed,
108            zoom
109        }
110    }
111}
112
113pub type ImageFormat = PixelFormat;
114
115#[derive(Default, Debug, PartialEq)]
116pub struct Effect2D {
117    program: Program,
118    projection: i32,
119    modelview: i32
120}
121
122impl Effect2D {
123    pub fn new(position: Option<String>, pixel: Option<String>) -> Result<Effect2D, String> {
124        let mut pos: Option<String> = position.clone();
125        let mut pix: Option<String> = pixel.clone();
126        if position == None {
127            pos = Some("vec4 position(vec2 pos, mat4 mvp) {
128                return mvp * vec4(pos, 0.0, 1.0);
129                // return projection * modelview * vec4(pos, 0.0, 1.0);
130            }".to_string());
131        }
132        if pixel == None {
133            pix = Some("vec4 pixel(vec4 color, vec2 texcoord, sampler2D text) {
134                return color * texture(text, texcoord);
135            }".to_string());
136        }
137
138        let vertex = ShaderBuilder::new()
139            .add_input::<Vec2>("a_Position")
140            .add_input::<Vec4>("a_Color")
141            .add_input::<Vec2>("a_Texcoord")
142            .add_output::<Vec4>("v_Color")
143            .add_output::<Vec2>("v_Texcoord")
144            .add_uniform::<Mat4>("u_MVP")
145            .push_pre_main(pos.unwrap().as_str())
146            .set_main("void main() {
147                gl_Position = position(a_Position, u_MVP);
148                v_Color = a_Color;
149                v_Texcoord = a_Texcoord;
150            }")
151            .build(ShaderType::VertexShader)
152            .unwrap();
153
154        let fragment = ShaderBuilder::new()
155            .add_input::<Vec4>("v_Color")
156            .add_input::<Vec2>("v_Texcoord")
157            .add_uniform::<Sampler2D>("u_Texture")
158            .push_pre_main(pix.unwrap().as_str())
159            .set_main("void main() {
160                gl_FragColor = pixel(v_Color, v_Texcoord, u_Texture);
161            }")
162            .build(ShaderType::FragmentShader)
163            .unwrap();
164
165        let program = Program::new().unwrap();
166        program.attach_shader(&vertex);
167        program.attach_shader(&fragment);
168        program.link().expect("Failed to link program");
169
170        let projection = program.get_uniform_location("u_Projection");
171        let modelview = program.get_uniform_location("u_Modelview");
172        // println!("{projection} {modelview}");
173        Ok(Effect2D {
174            program,
175            projection,
176            modelview
177        })
178    }
179}
180
181impl Effect for Effect2D {
182    fn send_uniform<T: GlUniform>(&self, name: &str, value: T) {
183        let location = self.program.get_uniform_location(name);
184        self.program.send_uniform(location, value);
185    }
186}
187
188#[derive(Default, Debug, PartialEq)]
189pub struct SpriteBatch {
190    vbo: VertexBuffer,
191    ibo: IndexBuffer,
192}
193
194#[derive(Default, Debug)]
195pub struct Render2D {
196    vao: VertexArray,
197    batch: SpriteBatch,
198    default_effect: Effect2D,
199    white_image: Image,
200    default_canvas: Canvas,
201
202    draw_mode: DrawMode,
203
204    clear_color: Color,
205    draw_color: Color,
206
207    camera: Camera2D,
208}
209
210impl Render2D {
211    pub fn clear_batch(&mut self) {
212        self.batch.clear();
213    }
214
215    pub fn set_clear_color(&mut self, color: Color) {
216        let v = color.to_vec4();
217        self.clear_color = color;
218        tea::clear_color(v.x, v.y, v.z, v.w);
219    }
220
221    pub fn set_draw_color(&mut self, color: Color) {
222        let v = color.to_vec4();
223        self.draw_color = color;
224        tea::clear_color(v.x, v.y, v.z, v.w);
225    }
226
227    pub fn clear_color(&self) -> Color { self.clear_color }
228    pub fn draw_color(&self) -> Color { self.draw_color }
229
230    fn set_draw_mode(&mut self, mode: DrawMode) {
231        if self.draw_mode != mode {
232            self.draw_and_clean();
233            self.draw_mode = mode;
234        }
235    }
236
237    fn set_image(&mut self, image: Option<&Image>) {
238        let i: &Image;
239        if image == None { i = &self.white_image; }
240        else { i = image.unwrap(); }
241        if Texture2D::current_bind() == i.texture.get_id() { return }
242        self.draw();
243        self.batch.clear();
244        i.texture.bind();
245    }
246
247    pub fn hello_triangle(&mut self) {
248        self.set_image(None);
249        self.set_draw_mode(DrawMode::Triangles);
250        let mut data: Vec<Vertex2D> = vec![];
251        data.push(Vertex2D::new(Vec2::new(128.0, 64.0), Vec4::new(1.0, 0.0, 0.0, 1.0), Vec2::new(0.0, 0.0)));
252        data.push(Vertex2D::new(Vec2::new(64.0, 128.0), Vec4::new(0.0, 1.0, 0.0, 1.0), Vec2::new(0.0, 0.0)));
253        data.push(Vertex2D::new(Vec2::new(196.0, 128.0), Vec4::new(0.0, 0.0, 1.0, 1.0), Vec2::new(0.0, 0.0)));
254        self.batch.push_vec(data);
255    }
256
257    pub fn blit(&mut self, draw: &impl Drawable, src: Option<&Rect>, x: f32, y: f32) {
258        self.set_draw_mode(DrawMode::Triangles);
259        let texture = draw.get_handle();
260        if Texture2D::current_bind() != texture.get_id() {
261            self.draw_and_clean();
262            texture.bind();
263        }
264        let mut rect = Rect::new(x, y, draw.get_width() as f32, draw.get_height() as f32);
265        let mut uv: Vec4 = Vec4::new(0.0, 0.0, 1.0, 1.0);
266        if src != None {
267            let rr = src.unwrap();
268            let width = draw.get_width() as f32;
269            let height = draw.get_height() as f32;
270            uv.x = rr.x / width;
271            uv.y = rr.y / height;
272            uv.z = (rr.x + rr.w) / width;
273            uv.w = (rr.y + rr.h) / height;
274
275            rect.w = rr.w;
276            rect.h = rr.h;
277        }
278
279        if draw.flip_y() {
280            uv.y = 1.0 - uv.y;
281            uv.w = 1.0 - uv.w;
282            // let aux = uv.y;
283            // uv.y = uv.w;
284            // uv.w = aux;
285        }
286
287        self.batch.add_quad(
288            Vec4::new(rect.x, rect.y, uv.x, uv.y),
289            Vec4::new(rect.x+rect.w, rect.y, uv.z, uv.y),
290            Vec4::new(rect.x+rect.w, rect.y+rect.h, uv.z, uv.w),
291            Vec4::new(rect.x, rect.y+rect.h, uv.x, uv.w),
292        );
293    }
294
295    pub fn blit_scale(&mut self, draw: &impl Drawable, src: Option<&Rect>, x: f32, y: f32, sx: f32, sy: f32) {
296        self.set_draw_mode(DrawMode::Triangles);
297        let texture = draw.get_handle();
298        if Texture2D::current_bind() != texture.get_id() {
299            self.draw_and_clean();
300            texture.bind();
301        }
302        let mut rect = Rect::new(x, y, draw.get_width() as f32, draw.get_height() as f32);
303        let mut uv = Vec4::new(0.0, 0.0, 1.0, 1.0);
304        if src != None {
305            let rr = src.unwrap();
306            let width = draw.get_width() as f32;
307            let height = draw.get_height() as f32;
308            uv.x = rr.x / width;
309            uv.y = rr.y / height;
310            uv.z = (rr.x + rr.w) / width;
311            uv.w = (rr.y + rr.h) / height;
312
313            rect.w = rr.w;
314            rect.h = rr.h;
315        }
316
317        if draw.flip_y() {
318            uv.y = 1.0 - uv.y;
319            uv.w = 1.0 - uv.w;
320        }
321        let width = rect.w * sx;
322        let height = rect.h * sy;
323        self.batch.add_quad(
324            Vec4::new(rect.x, rect.y, uv.x, uv.y),
325            Vec4::new(rect.x+width, rect.y, uv.z, uv.y),
326            Vec4::new(rect.x+width, rect.y+height, uv.z, uv.w),
327            Vec4::new(rect.x, rect.y+height, uv.x, uv.w),
328        );
329    }
330
331    pub fn blit_rotate(&mut self, draw: &impl Drawable, src: Option<&Rect>, x: f32, y: f32, angle: f32) {
332        self.set_draw_mode(DrawMode::Triangles);
333        let texture = draw.get_handle();
334        if Texture2D::current_bind() != texture.get_id() {
335            self.draw_and_clean();
336            texture.bind();
337        }
338        let mut rect = Rect::new(x, y, draw.get_width() as f32, draw.get_height() as f32);
339        let mut uv = Vec4::new(0.0, 0.0, 1.0, 1.0);
340        if src != None {
341            let rr = src.unwrap();
342            let width = draw.get_width() as f32;
343            let height = draw.get_height() as f32;
344            uv.x = rr.x / width;
345            uv.y = rr.y / height;
346            uv.z = (rr.x + rr.w) / width;
347            uv.w = (rr.y + rr.h) / height;
348
349            rect.w = rr.w;
350            rect.h = rr.h;
351        }
352
353        if draw.flip_y() {
354            uv.y = 1.0 - uv.y;
355            uv.w = 1.0 - uv.w;
356        }
357        let width = rect.w;
358        let height = rect.h;
359        let mut data: [Vec4; 4] = [
360            Vec4::new(rect.x, rect.y, 0.0, 1.0),
361            Vec4::new(rect.x+width, rect.y, 0.0, 1.0),
362            Vec4::new(rect.x+width, rect.y+height, 0.0, 1.0),
363            Vec4::new(rect.x, rect.y+height, 0.0, 1.0),
364        ];
365        /*
366            Vec4::new(0.0, 0.0, 0.0, 0.0),
367            Vec4::new(1.0, 0.0, 0.0, 0.0),
368            Vec4::new(1.0, 1.0, 0.0, 0.0),
369            Vec4::new(0.0, 1.0, 0.0, 0.0),
370        */
371        /*
372            Vec4::new(rect.x, rect.y, 0.0, 0.0),
373            Vec4::new(rect.x+width, rect.y, 0.0, 0.0),
374            Vec4::new(rect.x+width, rect.y+height, 0.0, 0.0),
375            Vec4::new(rect.x, rect.y+height, 0.0, 0.0),
376        */
377        let mut m = Mat4::identity();
378        m.translate(Vec3::new(-x, -y, 0.0));
379        m.rotate(angle);
380        m.translate(Vec3::new(x, y, 0.0));
381        // println!("{m:?}");
382        for d in &mut data {
383            d.apply_matrix(m);
384        }
385        data[0].z = uv.x;
386        data[0].w = uv.y;
387
388        data[1].z = uv.z;
389        data[1].w = uv.y;
390
391        data[2].z = uv.z;
392        data[2].w = uv.w;
393
394        data[3].z = uv.x;
395        data[3].w = uv.w;
396
397        self.batch.add_quad(
398            data[0], data[1], data[2], data[3],
399        );
400    }
401
402    pub fn blit_ex(&mut self, draw: &impl Drawable, src: Option<&Rect>, x: f32, y: f32, angle: f32, sx: f32, sy: f32) {
403        self.set_draw_mode(DrawMode::Triangles);
404        let texture = draw.get_handle();
405        if Texture2D::current_bind() != texture.get_id() {
406            self.draw_and_clean();
407            texture.bind();
408        }
409        let mut rect = Rect::new(x, y, draw.get_width() as f32, draw.get_height() as f32);
410        let mut uv = Vec4::new(0.0, 0.0, 1.0, 1.0);
411        if src != None {
412            let rr = src.unwrap();
413            let width = draw.get_width() as f32;
414            let height = draw.get_height() as f32;
415            uv.x = rr.x / width;
416            uv.y = rr.y / height;
417            uv.z = (rr.x + rr.w) / width;
418            uv.w = (rr.y + rr.h) / height;
419
420            rect.w = rr.w;
421            rect.h = rr.h;
422        }
423
424        if draw.flip_y() {
425            uv.y = 1.0 - uv.y;
426            uv.w = 1.0 - uv.w;
427        }
428        let width = rect.w;
429        let height = rect.h;
430        let mut data: [Vec4; 4] = [
431            Vec4::new(rect.x, rect.y, 0.0, 1.0),
432            Vec4::new(rect.x+width, rect.y, 0.0, 1.0),
433            Vec4::new(rect.x+width, rect.y+height, 0.0, 1.0),
434            Vec4::new(rect.x, rect.y+height, 0.0, 1.0),
435        ];
436
437        let mut m = Mat4::identity();
438        m.translate(Vec3::new(-x, -y, 0.0));
439        m.rotate(angle);
440        m.translate(Vec3::new(x, y, 0.0));
441        m.scale(Vec3::new(sx, sy, 1.0));
442        // println!("{m:?}");
443        for d in &mut data {
444            d.apply_matrix(m);
445        }
446        data[0].z = uv.x;
447        data[0].w = uv.y;
448
449        data[1].z = uv.z;
450        data[1].w = uv.y;
451
452        data[2].z = uv.z;
453        data[2].w = uv.w;
454
455        data[3].z = uv.x;
456        data[3].w = uv.w;
457
458        self.batch.add_quad(
459            data[0], data[1], data[2], data[3],
460        );
461    }
462
463    pub fn draw_triangle(&mut self, p0: Vec2, p1: Vec2, p2: Vec2) {
464        self.set_draw_mode(DrawMode::Lines);
465        self.set_image(None);
466        self.batch.push(Vertex2D::from_position(p0.x, p0.y));
467        self.batch.push(Vertex2D::from_position(p1.x, p1.y));
468
469        self.batch.push(Vertex2D::from_position(p1.x, p1.y));
470        self.batch.push(Vertex2D::from_position(p2.x, p2.y));
471
472        self.batch.push(Vertex2D::from_position(p2.x, p2.y));
473        self.batch.push(Vertex2D::from_position(p0.x, p0.y));
474    }
475
476    pub fn fill_triangle(&mut self, p0: Vec2, p1: Vec2, p2: Vec2) {
477        self.set_draw_mode(DrawMode::Triangles);
478        self.set_image(None);
479
480        let mut data: Vec<Vertex2D> = vec![];
481
482        data.push(Vertex2D::from_position(p0.x, p0.y));
483        data.push(Vertex2D::from_position(p1.x, p1.y));
484        data.push(Vertex2D::from_position(p2.x, p2.y));
485
486        self.batch.push_vec(data);
487    }
488
489    pub fn fill_rect(&mut self, rect: &Rect) {
490        self.set_draw_mode(DrawMode::Triangles);
491        self.set_image(None);
492        self.batch.add_rect(rect);
493    }
494
495    pub fn draw_rect(&mut self, rect: &Rect) {
496        self.set_draw_mode(DrawMode::Lines);
497        self.set_image(None);
498        let mut data: Vec<Vertex2D> = vec![];
499        data.push(Vertex2D::from_position(rect.x, rect.y));
500        data.push(Vertex2D::from_position(rect.x+rect.w, rect.y));
501
502        data.push(Vertex2D::from_position(rect.x+rect.w, rect.y));
503        data.push(Vertex2D::from_position(rect.x+rect.w, rect.y+rect.h));
504
505        data.push(Vertex2D::from_position(rect.x, rect.y+rect.h));
506        data.push(Vertex2D::from_position(rect.x+rect.w, rect.y+rect.h));
507
508        data.push(Vertex2D::from_position(rect.x, rect.y));
509        data.push(Vertex2D::from_position(rect.x, rect.y+rect.h));
510
511        self.batch.push_vec(data);
512    }
513
514    pub fn draw_circle(&mut self, cx: f32, cy: f32, radius: f32) {
515        self.set_draw_mode(DrawMode::Lines);
516        self.set_image(None);
517        let sides = 32;
518        let p0 = Vec2::new(cx, cy);
519        let pi2 = std::f32::consts::PI * 2.0;
520        let mut data: Vec<Vertex2D> = vec![];
521        for i in 0..sides {
522            let tetha = (i as f32 * pi2) / sides as f32;
523            let tetha2 = ((i + 1) as f32 * pi2) / sides as f32;
524            let p1 = p0 + Vec2::new(tetha.cos() * radius, tetha.sin() * radius);
525            let p2 = p0 + Vec2::new(tetha2.cos() * radius, tetha2.sin() * radius);
526            data.push(Vertex2D::from_position(p1.x, p1.y));
527            data.push(Vertex2D::from_position(p2.x, p2.y));
528        }
529        self.batch.push_vec(data);
530    }
531
532    pub fn fill_circle(&mut self, cx: f32, cy: f32, radius: f32) {
533        self.set_draw_mode(DrawMode::Triangles);
534        self.set_image(None);
535        let sides = 32;
536        let pi2 = std::f32::consts::PI * 2.0;
537        let p0 = Vec2::new(cx, cy);
538        let mut data: Vec<Vertex2D> = vec![];
539        for i in 0..sides {
540            let tetha = (i as f32 * pi2) / sides as f32;
541            let tetha2 = ((i + 1) as f32 * pi2) / sides as f32;
542                let p1 = p0 + Vec2::new(tetha.cos() * radius, tetha.sin() * radius);
543            let p2 = p0 + Vec2::new(tetha2.cos() * radius, tetha2.sin() * radius);
544            data.push(Vertex2D::from_position(p0.x, p0.y));
545            data.push(Vertex2D::from_position(p1.x, p1.y));
546            data.push(Vertex2D::from_position(p2.x, p2.y));
547        }
548        self.batch.push_vec(data);
549    }
550
551    fn draw(&self) {
552        if self.batch.count() <= 0 { return }
553        self.batch.flush();
554        self.vao.bind();
555        tea::draw_arrays(self.draw_mode, 0, self.batch.count() as i32);
556        self.vao.unbind();
557    }
558
559    fn draw_and_clean(&mut self) {
560        let mvp = self.camera().view() * self.camera.projection();
561        mvp.send_uniform(0);
562        self.draw();
563        self.batch.clear();
564    }
565}
566
567impl Render for Render2D {
568    type Effect = Effect2D;
569    fn new() -> Self {
570        let vao = VertexArray::new().unwrap();
571        let batch = SpriteBatch::new(1000).unwrap();
572        // println!("{:?}", batch);
573
574        vao.bind();
575        batch.vbo.handle.bind();
576        vao.setup_for::<Vertex2D>();
577        vao.unbind();
578        batch.vbo.handle.unbind();
579
580        // let default_effect = Effect::from_default().unwrap();
581        let default_effect = Effect2D::new(None, None).unwrap();
582        let default_canvas = Canvas::default();
583        let white_image = Image::new(1, 1, ImageFormat::RGBA, vec![255, 255, 255, 255]).unwrap();
584        // println!("{:?}", white_image);
585        let clear_color = Color::black();
586        let draw_color = Color::white();
587        let camera = Camera2D::new(640.0, 380.0);
588        Render2D {
589            vao,
590            batch,
591            default_effect,
592            white_image,
593            default_canvas,
594            clear_color,
595            draw_color,
596            camera,
597            ..Default::default()
598        }
599    }
600
601    fn begin(&mut self) {
602        self.set_image(None);
603        self.set_canvas(None);
604        self.set_effect(None);
605        self.batch.clear();
606        tea::enable(&[EnableFlags::Blend]);
607        tea::blend_func(BlendFunc::SrcAlpha, BlendFunc::OneMinusSrcAlpha);
608    }
609
610    fn end(&self) {
611        self.draw();
612        tea::disable(&[EnableFlags::Blend]);
613    }
614
615    fn set_canvas(&mut self, canvas: Option<&Canvas>) {
616        let c: &Canvas;
617        if canvas == None { c = &self.default_canvas; }
618        else { c = canvas.unwrap(); }
619        if Framebuffer::current_bind() == c.framebuffer.get_id() { return }
620        self.draw();
621        self.batch.clear();
622        c.framebuffer.bind();
623        let right = c.width as f32;
624        let bottom = c.height as f32;
625        self.camera.set_size(right, bottom);
626        tea::viewport(0, 0, c.width, c.height);
627    }
628
629    fn set_effect(&mut self, effect: Option<&Self::Effect>) {
630        let e: &Self::Effect;
631        if effect == None { e = &self.default_effect; }
632        else { e = effect.unwrap(); }
633        e.program.set_used();
634        (self.camera.view() * self.camera.projection()).send_uniform(0);
635    }
636
637    fn on_resize(&mut self, width: i32, height: i32) {
638        self.default_canvas.width = width;
639        self.default_canvas.height = height;
640        self.camera.set_size(width as f32, height as f32);
641        tea::viewport(0, 0, width, height);
642    }
643
644    fn camera(&mut self) -> &mut dyn Camera {
645        &mut self.camera
646    }
647}
648
649/* Impl SpriteBatch */
650impl SpriteBatch {
651    pub fn new(count: usize) -> Result<Self, String> {
652        let vbo = VertexBuffer::new(count).unwrap();
653        let ibo = IndexBuffer::new(count).unwrap();
654        Ok(SpriteBatch {
655            vbo,
656            ibo,
657        })
658    }
659
660    #[cfg(target = "")]
661    fn grow(&mut self) {
662        let count = self.data.capacity();
663        let mut v: Vec<Vertex2D> = Vec::with_capacity(count);
664        self.data.append(&mut v);
665        self.vbo.bind();
666        self.vbo.data(self.data.len() * Vertex2D::stride(), self.data.as_ptr() as *const c_void, BufferUsage::DynamicDraw);
667        self.vbo.unbind();
668    }
669
670    pub fn push(&mut self, data: Vertex2D) {
671        if self.vbo.len() + 1 >= self.vbo.capacity() {
672            self.vbo.grow();
673            self.ibo.grow();
674        }
675        self.vbo.push(data);
676        /*
677        if self.data.len() + 1 >= self.data.capacity() {
678            self.grow();
679        }
680        self.data.push(data);
681        */
682    }
683
684    pub fn push_vec(&mut self, data: Vec<Vertex2D>) {
685        if self.vbo.len() + data.len() >= self.vbo.capacity() {
686            self.vbo.grow();
687            self.ibo.grow();
688        }
689        self.vbo.push_vec(data);
690    }
691
692    pub fn add_rect(&mut self, rect: &Rect) {
693        self.add_quad(
694            Vec4::new(rect.x, rect.y, 0.0, 0.0),
695            Vec4::new(rect.x+rect.w, rect.y, 1.0, 0.0),
696            Vec4::new(rect.x+rect.w, rect.y+rect.h, 1.0, 1.0),
697            Vec4::new(rect.x, rect.y+rect.h, 0.0, 1.0),
698        );
699    }
700
701    pub fn add_quad(&mut self, v0: Vec4, v1: Vec4, v2: Vec4, v3: Vec4) {
702        let mut data: Vec<Vertex2D> = vec![];
703        data.push(Vertex2D::from_pos_uv(v0.x, v0.y, v0.z, v0.w));
704        data.push(Vertex2D::from_pos_uv(v1.x, v1.y, v1.z, v1.w));
705        data.push(Vertex2D::from_pos_uv(v2.x, v2.y, v2.z, v2.w));
706
707        data.push(Vertex2D::from_pos_uv(v0.x, v0.y, v0.z, v0.w));
708        data.push(Vertex2D::from_pos_uv(v2.x, v2.y, v2.z, v2.w));
709        data.push(Vertex2D::from_pos_uv(v3.x, v3.y, v3.z, v3.w));
710        self.push_vec(data);
711    }
712
713    pub fn flush(&self) {
714        self.vbo.flush();
715    }
716
717    pub fn count(&self) -> usize { self.vbo.len() }
718
719    pub fn clear(&mut self) {
720        self.vbo.clear();
721    }
722}
723
724/* Impl Vertex2D */
725impl Default for Vertex2D {
726    fn default() -> Self {
727        Vertex2D (
728            Vec2::new(0.0, 0.0),
729            Vec4::new(0.0, 0.0, 0.0, 0.0),
730            Vec2::new(0.0, 0.0),
731        )
732    }
733}
734
735impl Vertex2D {
736    pub fn new(pos: Vec2, color: Vec4, texcoord: Vec2) -> Self {
737        Vertex2D(
738            pos,
739            color,
740            texcoord
741        )
742    }
743
744    pub fn from_position(x: f32, y: f32) -> Self {
745
746        Vertex2D(
747            Vec2::new(x, y),
748            Vec4::new(1.0, 1.0, 1.0, 1.0),
749            Vec2::new(0.0, 0.0)
750        )
751    }
752    
753    pub fn from_pos_uv(x: f32, y: f32, u: f32, v: f32) -> Self {
754        Vertex2D (
755            Vec2::new(x, y),
756            Vec4::new(1.0, 1.0, 1.0, 1.0),
757            Vec2::new(u, v)
758        )
759    }
760}