forked from fogleman/fauxgl
-
Notifications
You must be signed in to change notification settings - Fork 1
/
texture.go
63 lines (56 loc) · 1.25 KB
/
texture.go
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
package fauxgl
import (
"image"
"math"
)
type Texture interface {
Sample(u, v float64) Color
BilinearSample(u, v float64) Color
}
func LoadTexture(path string) (Texture, error) {
im, err := LoadImage(path)
if err != nil {
return nil, err
}
return NewImageTexture(im), nil
}
type ImageTexture struct {
Width int
Height int
Image image.Image
}
func NewImageTexture(im image.Image) Texture {
size := im.Bounds().Max
return &ImageTexture{size.X, size.Y, im}
}
func (t *ImageTexture) Sample(u, v float64) Color {
v = 1 - v
u -= math.Floor(u)
v -= math.Floor(v)
x := int(u * float64(t.Width))
y := int(v * float64(t.Height))
return MakeColor(t.Image.At(x, y))
}
func (t *ImageTexture) BilinearSample(u, v float64) Color {
v = 1 - v
u -= math.Floor(u)
v -= math.Floor(v)
x := u * float64(t.Width-1)
y := v * float64(t.Height-1)
x0 := int(x)
y0 := int(y)
x1 := x0 + 1
y1 := y0 + 1
x -= float64(x0)
y -= float64(y0)
c00 := MakeColor(t.Image.At(x0, y0))
c01 := MakeColor(t.Image.At(x0, y1))
c10 := MakeColor(t.Image.At(x1, y0))
c11 := MakeColor(t.Image.At(x1, y1))
c := Color{}
c = c.Add(c00.MulScalar((1 - x) * (1 - y)))
c = c.Add(c10.MulScalar(x * (1 - y)))
c = c.Add(c01.MulScalar((1 - x) * y))
c = c.Add(c11.MulScalar(x * y))
return c
}