1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::path::Path;
use std::rc::Rc;
use image;
use crate::error::Result;
use crate::graphics::opengl::{GLTexture, TextureFormat};
use crate::graphics::{self, DrawParams, Drawable, Rectangle};
use crate::Context;
#[derive(Debug, Clone, PartialEq)]
pub struct Texture {
pub(crate) handle: Rc<GLTexture>,
}
impl Texture {
pub fn new<P>(ctx: &mut Context, path: P) -> Result<Texture>
where
P: AsRef<Path>,
{
let image = image::open(path)?.to_rgba();
let (width, height) = image.dimensions();
let texture = ctx
.gl
.new_texture(width as i32, height as i32, TextureFormat::Rgba);
ctx.gl.set_texture_data(
&texture,
&image,
0,
0,
width as i32,
height as i32,
TextureFormat::Rgba,
);
Ok(Texture::from_handle(texture))
}
pub(crate) fn from_handle(handle: GLTexture) -> Texture {
Texture {
handle: Rc::new(handle),
}
}
pub fn width(&self) -> i32 {
self.handle.width()
}
pub fn height(&self) -> i32 {
self.handle.height()
}
}
impl Drawable for Texture {
fn draw<P>(&self, ctx: &mut Context, params: P)
where
P: Into<DrawParams>,
{
let params = params.into();
let texture_width = self.width() as f32;
let texture_height = self.height() as f32;
let clip = params
.clip
.unwrap_or_else(|| Rectangle::new(0.0, 0.0, texture_width, texture_height));
let x1 = 0.0;
let y1 = 0.0;
let x2 = clip.width;
let y2 = clip.height;
let u1 = clip.x / texture_width;
let v1 = clip.y / texture_height;
let u2 = (clip.x + clip.width) / texture_width;
let v2 = (clip.y + clip.height) / texture_height;
graphics::set_texture(ctx, self);
graphics::push_quad(ctx, x1, y1, x2, y2, u1, v1, u2, v2, ¶ms);
}
}