cafe/
render.rs

1extern crate tea;
2
3use tea::{GlUniform, GlBind};
4use tea::texture::{Texture2D, GlTexture};
5use crate::{Mat4, Vec4, Vec3, Rect};
6
7use tea::buffer::{GlBuffer, BufferUsage};
8use tea::target::{Framebuffer, FramebufferAttachment};
9
10pub use tea::texture::{TexTarget, TexFilter, TexWrap, TexParam, PixelFormat, PixelDataType};
11
12#[allow(non_snake_case)]
13pub mod render2D;
14#[allow(non_snake_case)]
15pub mod render3D;
16
17#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
18pub struct Color(u8, u8, u8, u8);
19
20impl Color {
21    pub fn rgb(r: u8, g: u8, b: u8) -> Color { Color(r, g, b, 255) }
22    pub fn rgba(r: u8, g: u8, b: u8, a: u8) -> Color { Color(r, g, b, a) }
23
24    pub fn black() -> Self { Self::rgb(0, 0, 0) }
25    pub fn white() -> Self { Self::rgb(255, 255, 255) }
26
27    pub fn to_vec4(&self) -> Vec4 {
28        let r = self.0 as f32 / 255.0;
29        let g = self.1 as f32 / 255.0;
30        let b = self.2 as f32 / 255.0;
31        let a = self.3 as f32 / 255.0;
32        Vec4::new(r, g, b, a)
33    }
34}
35
36pub enum Movement {
37    Left,
38    Right,
39    Up,
40    Down,
41    Forward,
42    Backward,
43}
44
45pub trait Camera {
46    fn position(&self) -> &Vec3;
47    fn set_position(&mut self, position: Vec3);
48
49    fn set_width(&mut self, width: f32);
50    fn set_height(&mut self, height: f32);
51    fn set_size(&mut self, width: f32, height: f32) { self.set_width(width); self.set_height(height); }
52    fn projection(&self) -> Mat4;
53    fn view(&self) -> Mat4;
54
55    fn move_camera(&mut self, dir: Movement, dt: f32);
56}
57
58pub trait Drawable {
59    fn get_handle(&self) -> &Texture2D;
60    fn get_width(&self) -> i32;
61    fn get_height(&self) -> i32;
62    fn flip_y(&self) -> bool { false }
63}
64
65pub trait Batch {
66    type DataType;
67    fn clear(&mut self);
68    fn capacity(&self) -> usize;
69    fn len(&self) -> usize;
70    fn grow(&mut self);
71    fn push(&mut self, value: Self::DataType);
72    fn push_vec(&mut self, values: Vec<Self::DataType>);
73    fn flush(&self);
74    fn flush_part(&self, offset: isize, size: usize);
75}
76
77#[derive(Default, Debug, PartialEq, Eq)]
78pub struct Image {
79    texture: Texture2D,
80    width: i32, height: i32,
81    filter: (TexFilter, TexFilter),
82    wrap: (TexWrap, TexWrap)
83}
84
85#[derive(Default, Debug, PartialEq, Eq)]
86pub struct Canvas {
87    framebuffer: Framebuffer,
88    texture: Texture2D,
89    width: i32, height: i32,
90    filter: (TexFilter, TexFilter),
91    wrap: (TexWrap, TexWrap),
92}
93
94#[derive(Default, Debug)]
95pub struct Buffer<K: GlBuffer, T> {
96    handle: K,
97    data: Vec<T>
98}
99
100impl<K: GlBuffer, T> PartialEq for Buffer<K, T> {
101    fn eq(&self, other: &Self) -> bool { self.handle.get_id() == other.handle.get_id() }
102}
103
104impl<K: GlBuffer, T> Batch for Buffer<K, T> {
105    type DataType = T;
106    fn clear(&mut self) { self.data.clear() }
107    fn capacity(&self) -> usize { self.data.capacity() }
108    fn len(&self) -> usize { self.data.len() }
109    fn push(&mut self, value: T) {
110        self.data.push(value);
111    }
112
113    fn push_vec(&mut self, values: Vec<T>) {
114        self.data.extend(values);
115    }
116
117    fn grow(&mut self) {
118        let count = self.data.capacity();
119        let v: Vec<T> = Vec::with_capacity(count);
120        let len = self.data.len();
121        self.data.extend(v);
122        unsafe { self.data.set_len(len); }
123        self.handle.bind();
124        self.handle.data(&self.data, BufferUsage::DynamicDraw);
125    }
126
127    fn flush(&self) {
128        self.handle.bind();
129        self.handle.subdata(0, self.data.len(), &self.data);
130        self.handle.unbind();
131    }
132
133    fn flush_part(&self, offset: isize, count: usize) {
134        self.handle.bind();
135        self.handle.subdata(offset, count, &self.data);
136        self.handle.unbind();
137    }
138}
139
140#[cfg(target="")]
141#[derive(Default, Debug)]
142pub struct VertexBuffer<T> {
143    handle: ArrayBuffer,
144    data: Vec<T>
145}
146
147impl Image {
148    fn new(width: i32, height: i32, format: PixelFormat, data: Vec<u8>) -> Result<Self, String> {
149        let texture = Texture2D::new().unwrap();
150        texture.bind();
151        texture.data(0, format, (width, height), PixelDataType::UByte, data);
152        texture.set_min_filter(TexFilter::default());
153        texture.set_mag_filter(TexFilter::default());
154        texture.unbind();
155        Ok(Image{
156            texture,
157            width, height,
158            ..Default::default()
159        })
160    }
161
162    pub fn load(filename: &str) -> Result<Self, String> {
163        let res = stb_image::image::load(filename);
164        match res {
165            stb_image::image::LoadResult::Error(s) => {
166                let err = format!("Failed to load image: {filename}: {s}");
167                return Err(err)
168            },
169            stb_image::image::LoadResult::ImageU8(i) => {
170                let format: PixelFormat;
171                match i.depth {
172                    3 => { format = PixelFormat::RGB },
173                    4 => { format = PixelFormat::RGBA },
174                    _ => { format = PixelFormat::RGBA }
175                }
176                return Image::new(i.width as i32, i.height as i32, format, i.data);
177            },
178            _ => {}
179        }
180        Ok(Image::default())
181    }
182
183    pub fn pixel_art(&self) {
184        self.texture.bind();
185        self.texture.set_min_filter(TexFilter::Nearest);
186        self.texture.set_mag_filter(TexFilter::Nearest);
187        self.texture.unbind();
188    }
189    
190    pub fn pixel(&self, x: i32, y: i32) -> Color {
191        Color::rgb(255, 255, 255)
192    }
193}
194
195impl Drawable for Image {
196    fn get_handle(&self) -> &Texture2D { &self.texture }
197    fn get_width(&self) -> i32 { self.width }
198    fn get_height(&self) -> i32 { self.height }
199}
200
201impl Canvas {
202    pub fn new(width: i32, height: i32) -> Result<Self, String> {
203        let framebuffer = Framebuffer::new().unwrap();
204        let texture = Texture2D::new().unwrap();
205        texture.bind();
206        texture.data(0, PixelFormat::RGBA, (width, height), PixelDataType::UByte, vec![]);
207        texture.set_min_filter(TexFilter::Linear);
208        texture.set_mag_filter(TexFilter::Linear);
209        texture.unbind();
210        framebuffer.bind();
211        framebuffer.attach_texture(FramebufferAttachment::ColorAttachment(0), &texture);
212        framebuffer.unbind();
213        Ok(Canvas{
214            framebuffer,
215            texture,
216            width,
217            height,
218            ..Default::default()
219        })
220    }
221
222    pub fn pixel_art(&self) {
223        self.texture.bind();
224        self.texture.set_min_filter(TexFilter::Nearest);
225        self.texture.set_mag_filter(TexFilter::Nearest);
226        self.texture.unbind();
227    }
228}
229
230impl Drawable for Canvas {
231    fn get_handle(&self) -> &Texture2D { &self.texture }
232    fn get_width(&self) -> i32 { self.width }
233    fn get_height(&self) -> i32 { self.height }
234    fn flip_y(&self) -> bool { true }
235}
236
237#[allow(dead_code)]
238#[derive(Default, Debug, PartialEq)]
239pub struct Font {
240    texture: Texture2D,
241    rect: Vec<Rect>,
242    size: u16
243}
244
245impl Font {
246    pub fn load(filename: &str) -> Result<Self, String> {
247        Ok(Font::default())
248    }
249}
250
251pub trait Effect {
252   fn send_uniform<T: GlUniform>(&self, name: &str, value: T);
253}
254
255pub trait Render {
256    type Effect: Effect;
257    fn new() -> Self;
258
259    fn clear_color(&self, color: Vec4) { tea::clear_color(color.x, color.y, color.z, color.w); }
260    fn clear(&self) { tea::clear(&[tea::ClearFlags::ColorBufferBit]) }
261
262    fn begin(&mut self);
263    fn end(&self);
264
265    fn camera(&mut self) -> &mut dyn Camera;
266
267    fn set_canvas(&mut self, canvas: Option<&Canvas>);
268    fn set_effect(&mut self, effect: Option<&Self::Effect>);
269
270    fn on_resize(&mut self, width: i32, height: i32);
271}