replace NRGBA to RGBA because Porter-Duff (!!!)
This commit is contained in:
parent
7d31dd8d6f
commit
f4916a4272
8
batch.go
8
batch.go
|
@ -13,7 +13,7 @@ type Batch struct {
|
||||||
cont Drawer
|
cont Drawer
|
||||||
|
|
||||||
mat Matrix
|
mat Matrix
|
||||||
col NRGBA
|
col RGBA
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ BasicTarget = (*Batch)(nil)
|
var _ BasicTarget = (*Batch)(nil)
|
||||||
|
@ -28,7 +28,7 @@ var _ BasicTarget = (*Batch)(nil)
|
||||||
func NewBatch(container Triangles, pic Picture) *Batch {
|
func NewBatch(container Triangles, pic Picture) *Batch {
|
||||||
b := &Batch{cont: Drawer{Triangles: container, Picture: pic}}
|
b := &Batch{cont: Drawer{Triangles: container, Picture: pic}}
|
||||||
b.SetMatrix(IM)
|
b.SetMatrix(IM)
|
||||||
b.SetColorMask(NRGBA{1, 1, 1, 1})
|
b.SetColorMask(RGBA{1, 1, 1, 1})
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +62,10 @@ func (b *Batch) SetMatrix(m Matrix) {
|
||||||
// SetColorMask sets a mask color used in the following draws onto the Batch.
|
// SetColorMask sets a mask color used in the following draws onto the Batch.
|
||||||
func (b *Batch) SetColorMask(c color.Color) {
|
func (b *Batch) SetColorMask(c color.Color) {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
b.col = NRGBA{1, 1, 1, 1}
|
b.col = RGBA{1, 1, 1, 1}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.col = ToNRGBA(c)
|
b.col = ToRGBA(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeTriangles returns a specialized copy of the provided Triangles that draws onto this Batch.
|
// MakeTriangles returns a specialized copy of the provided Triangles that draws onto this Batch.
|
||||||
|
|
77
color.go
77
color.go
|
@ -2,17 +2,17 @@ package pixel
|
||||||
|
|
||||||
import "image/color"
|
import "image/color"
|
||||||
|
|
||||||
// NRGBA represents a non-alpha-premultiplied RGBA color with components within range [0, 1].
|
// RGBA represents a alpha-premultiplied RGBA color with components within range [0, 1].
|
||||||
//
|
//
|
||||||
// The difference between color.NRGBA is that the value range is [0, 1] and the values are floats.
|
// The difference between color.RGBA is that the value range is [0, 1] and the values are floats.
|
||||||
type NRGBA struct {
|
type RGBA struct {
|
||||||
R, G, B, A float64
|
R, G, B, A float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add adds color d to color c component-wise and returns the result (the components are not
|
// Add adds color d to color c component-wise and returns the result (the components are not
|
||||||
// clamped).
|
// clamped).
|
||||||
func (c NRGBA) Add(d NRGBA) NRGBA {
|
func (c RGBA) Add(d RGBA) RGBA {
|
||||||
return NRGBA{
|
return RGBA{
|
||||||
R: c.R + d.R,
|
R: c.R + d.R,
|
||||||
G: c.G + d.G,
|
G: c.G + d.G,
|
||||||
B: c.B + d.B,
|
B: c.B + d.B,
|
||||||
|
@ -22,8 +22,8 @@ func (c NRGBA) Add(d NRGBA) NRGBA {
|
||||||
|
|
||||||
// Sub subtracts color d from color c component-wise and returns the result (the components
|
// Sub subtracts color d from color c component-wise and returns the result (the components
|
||||||
// are not clamped).
|
// are not clamped).
|
||||||
func (c NRGBA) Sub(d NRGBA) NRGBA {
|
func (c RGBA) Sub(d RGBA) RGBA {
|
||||||
return NRGBA{
|
return RGBA{
|
||||||
R: c.R - d.R,
|
R: c.R - d.R,
|
||||||
G: c.G - d.G,
|
G: c.G - d.G,
|
||||||
B: c.B - d.B,
|
B: c.B - d.B,
|
||||||
|
@ -32,8 +32,8 @@ func (c NRGBA) Sub(d NRGBA) NRGBA {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mul multiplies color c by color d component-wise (the components are not clamped).
|
// Mul multiplies color c by color d component-wise (the components are not clamped).
|
||||||
func (c NRGBA) Mul(d NRGBA) NRGBA {
|
func (c RGBA) Mul(d RGBA) RGBA {
|
||||||
return NRGBA{
|
return RGBA{
|
||||||
R: c.R * d.R,
|
R: c.R * d.R,
|
||||||
G: c.G * d.G,
|
G: c.G * d.G,
|
||||||
B: c.B * d.B,
|
B: c.B * d.B,
|
||||||
|
@ -43,8 +43,8 @@ func (c NRGBA) Mul(d NRGBA) NRGBA {
|
||||||
|
|
||||||
// Scaled multiplies each component of color c by scale and returns the result (the components
|
// Scaled multiplies each component of color c by scale and returns the result (the components
|
||||||
// are not clamped).
|
// are not clamped).
|
||||||
func (c NRGBA) Scaled(scale float64) NRGBA {
|
func (c RGBA) Scaled(scale float64) RGBA {
|
||||||
return NRGBA{
|
return RGBA{
|
||||||
R: c.R * scale,
|
R: c.R * scale,
|
||||||
G: c.G * scale,
|
G: c.G * scale,
|
||||||
B: c.B * scale,
|
B: c.B * scale,
|
||||||
|
@ -52,37 +52,23 @@ func (c NRGBA) Scaled(scale float64) NRGBA {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RGBA returns alpha-premultiplied red, green, blue and alpha components of the NRGBA color.
|
// RGBA returns alpha-premultiplied red, green, blue and alpha components of the RGBA color.
|
||||||
func (c NRGBA) RGBA() (r, g, b, a uint32) {
|
func (c RGBA) RGBA() (r, g, b, a uint32) {
|
||||||
c.R = clamp(c.R, 0, 1)
|
r = uint32(0xffff * c.R)
|
||||||
c.G = clamp(c.G, 0, 1)
|
g = uint32(0xffff * c.G)
|
||||||
c.B = clamp(c.B, 0, 1)
|
b = uint32(0xffff * c.B)
|
||||||
c.A = clamp(c.A, 0, 1)
|
|
||||||
r = uint32(0xffff * c.R * c.A)
|
|
||||||
g = uint32(0xffff * c.G * c.A)
|
|
||||||
b = uint32(0xffff * c.B * c.A)
|
|
||||||
a = uint32(0xffff * c.A)
|
a = uint32(0xffff * c.A)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func clamp(x, low, high float64) float64 {
|
// ToRGBA converts a color to RGBA format. Using this function is preferred to using RGBAModel, for
|
||||||
if x < low {
|
// performance (using RGBAModel introduced additional unnecessary allocations).
|
||||||
return low
|
func ToRGBA(c color.Color) RGBA {
|
||||||
}
|
if c, ok := c.(RGBA); ok {
|
||||||
if x > high {
|
|
||||||
return high
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToNRGBA converts a color to NRGBA format. Using this function is preferred to using NRGBAModel,
|
|
||||||
// for performance (using NRGBAModel introduced additional unnecessary allocations).
|
|
||||||
func ToNRGBA(c color.Color) NRGBA {
|
|
||||||
if c, ok := c.(NRGBA); ok {
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
if c, ok := c.(color.NRGBA); ok {
|
if c, ok := c.(color.RGBA); ok {
|
||||||
return NRGBA{
|
return RGBA{
|
||||||
R: float64(c.R) / 255,
|
R: float64(c.R) / 255,
|
||||||
G: float64(c.G) / 255,
|
G: float64(c.G) / 255,
|
||||||
B: float64(c.B) / 255,
|
B: float64(c.B) / 255,
|
||||||
|
@ -90,20 +76,17 @@ func ToNRGBA(c color.Color) NRGBA {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r, g, b, a := c.RGBA()
|
r, g, b, a := c.RGBA()
|
||||||
if a == 0 {
|
return RGBA{
|
||||||
return NRGBA{0, 0, 0, 0}
|
float64(r) / 0xffff,
|
||||||
}
|
float64(g) / 0xffff,
|
||||||
return NRGBA{
|
float64(b) / 0xffff,
|
||||||
float64(r) / float64(a),
|
|
||||||
float64(g) / float64(a),
|
|
||||||
float64(b) / float64(a),
|
|
||||||
float64(a) / 0xffff,
|
float64(a) / 0xffff,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NRGBAModel converts colors to NRGBA format.
|
// RGBAModel converts colors to RGBA format.
|
||||||
var NRGBAModel = color.ModelFunc(nrgbaModel)
|
var RGBAModel = color.ModelFunc(rgbaModel)
|
||||||
|
|
||||||
func nrgbaModel(c color.Color) color.Color {
|
func rgbaModel(c color.Color) color.Color {
|
||||||
return ToNRGBA(c)
|
return ToRGBA(c)
|
||||||
}
|
}
|
||||||
|
|
90
data.go
90
data.go
|
@ -12,7 +12,7 @@ import (
|
||||||
// TrianglesPosition, TrianglesColor and TrianglesPicture.
|
// TrianglesPosition, TrianglesColor and TrianglesPicture.
|
||||||
type TrianglesData []struct {
|
type TrianglesData []struct {
|
||||||
Position Vec
|
Position Vec
|
||||||
Color NRGBA
|
Color RGBA
|
||||||
Picture Vec
|
Picture Vec
|
||||||
Intensity float64
|
Intensity float64
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,10 @@ func (td *TrianglesData) SetLen(len int) {
|
||||||
for i := 0; i < needAppend; i++ {
|
for i := 0; i < needAppend; i++ {
|
||||||
*td = append(*td, struct {
|
*td = append(*td, struct {
|
||||||
Position Vec
|
Position Vec
|
||||||
Color NRGBA
|
Color RGBA
|
||||||
Picture Vec
|
Picture Vec
|
||||||
Intensity float64
|
Intensity float64
|
||||||
}{V(0, 0), NRGBA{1, 1, 1, 1}, V(0, 0), 0})
|
}{V(0, 0), RGBA{1, 1, 1, 1}, V(0, 0), 0})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len < td.Len() {
|
if len < td.Len() {
|
||||||
|
@ -108,7 +108,7 @@ func (td *TrianglesData) Position(i int) Vec {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color returns the color property of i-th vertex.
|
// Color returns the color property of i-th vertex.
|
||||||
func (td *TrianglesData) Color(i int) NRGBA {
|
func (td *TrianglesData) Color(i int) RGBA {
|
||||||
return (*td)[i].Color
|
return (*td)[i].Color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,10 +126,10 @@ func (td *TrianglesData) Picture(i int) (pic Vec, intensity float64) {
|
||||||
//
|
//
|
||||||
// The struct's innards are exposed for convenience, manual modification is at your own risk.
|
// The struct's innards are exposed for convenience, manual modification is at your own risk.
|
||||||
//
|
//
|
||||||
// The format of the pixels is color.NRGBA and not pixel.NRGBA for a very serious reason:
|
// The format of the pixels is color.RGBA and not pixel.RGBA for a very serious reason:
|
||||||
// pixel.NRGBA takes up 8x more memory than color.NRGBA.
|
// pixel.RGBA takes up 8x more memory than color.RGBA.
|
||||||
type PictureData struct {
|
type PictureData struct {
|
||||||
Pix []color.NRGBA
|
Pix []color.RGBA
|
||||||
Stride int
|
Stride int
|
||||||
Rect Rect
|
Rect Rect
|
||||||
}
|
}
|
||||||
|
@ -142,18 +142,18 @@ func MakePictureData(rect Rect) *PictureData {
|
||||||
Stride: w,
|
Stride: w,
|
||||||
Rect: rect,
|
Rect: rect,
|
||||||
}
|
}
|
||||||
pd.Pix = make([]color.NRGBA, w*h)
|
pd.Pix = make([]color.RGBA, w*h)
|
||||||
return pd
|
return pd
|
||||||
}
|
}
|
||||||
|
|
||||||
func verticalFlip(nrgba *image.NRGBA) {
|
func verticalFlip(rgba *image.RGBA) {
|
||||||
bounds := nrgba.Bounds()
|
bounds := rgba.Bounds()
|
||||||
width := bounds.Dx()
|
width := bounds.Dx()
|
||||||
|
|
||||||
tmpRow := make([]uint8, width*4)
|
tmpRow := make([]uint8, width*4)
|
||||||
for i, j := 0, bounds.Dy()-1; i < j; i, j = i+1, j-1 {
|
for i, j := 0, bounds.Dy()-1; i < j; i, j = i+1, j-1 {
|
||||||
iRow := nrgba.Pix[i*nrgba.Stride : i*nrgba.Stride+width*4]
|
iRow := rgba.Pix[i*rgba.Stride : i*rgba.Stride+width*4]
|
||||||
jRow := nrgba.Pix[j*nrgba.Stride : j*nrgba.Stride+width*4]
|
jRow := rgba.Pix[j*rgba.Stride : j*rgba.Stride+width*4]
|
||||||
|
|
||||||
copy(tmpRow, iRow)
|
copy(tmpRow, iRow)
|
||||||
copy(iRow, jRow)
|
copy(iRow, jRow)
|
||||||
|
@ -165,28 +165,28 @@ func verticalFlip(nrgba *image.NRGBA) {
|
||||||
//
|
//
|
||||||
// The resulting PictureData's Bounds will be the equivalent of the supplied image.Image's Bounds.
|
// The resulting PictureData's Bounds will be the equivalent of the supplied image.Image's Bounds.
|
||||||
func PictureDataFromImage(img image.Image) *PictureData {
|
func PictureDataFromImage(img image.Image) *PictureData {
|
||||||
var nrgba *image.NRGBA
|
var rgba *image.RGBA
|
||||||
if nrgbaImg, ok := img.(*image.NRGBA); ok {
|
if rgbaImg, ok := img.(*image.RGBA); ok {
|
||||||
nrgba = nrgbaImg
|
rgba = rgbaImg
|
||||||
} else {
|
} else {
|
||||||
nrgba = image.NewNRGBA(img.Bounds())
|
rgba = image.NewRGBA(img.Bounds())
|
||||||
draw.Draw(nrgba, nrgba.Bounds(), img, img.Bounds().Min, draw.Src)
|
draw.Draw(rgba, rgba.Bounds(), img, img.Bounds().Min, draw.Src)
|
||||||
}
|
}
|
||||||
|
|
||||||
verticalFlip(nrgba)
|
verticalFlip(rgba)
|
||||||
|
|
||||||
pd := MakePictureData(R(
|
pd := MakePictureData(R(
|
||||||
float64(nrgba.Bounds().Min.X),
|
float64(rgba.Bounds().Min.X),
|
||||||
float64(nrgba.Bounds().Min.Y),
|
float64(rgba.Bounds().Min.Y),
|
||||||
float64(nrgba.Bounds().Dx()),
|
float64(rgba.Bounds().Dx()),
|
||||||
float64(nrgba.Bounds().Dy()),
|
float64(rgba.Bounds().Dy()),
|
||||||
))
|
))
|
||||||
|
|
||||||
for i := range pd.Pix {
|
for i := range pd.Pix {
|
||||||
pd.Pix[i].R = nrgba.Pix[i*4+0]
|
pd.Pix[i].R = rgba.Pix[i*4+0]
|
||||||
pd.Pix[i].G = nrgba.Pix[i*4+1]
|
pd.Pix[i].G = rgba.Pix[i*4+1]
|
||||||
pd.Pix[i].B = nrgba.Pix[i*4+2]
|
pd.Pix[i].B = rgba.Pix[i*4+2]
|
||||||
pd.Pix[i].A = nrgba.Pix[i*4+3]
|
pd.Pix[i].A = rgba.Pix[i*4+3]
|
||||||
}
|
}
|
||||||
|
|
||||||
return pd
|
return pd
|
||||||
|
@ -220,33 +220,33 @@ func PictureDataFromPicture(pic Picture) *PictureData {
|
||||||
return pd
|
return pd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image converts PictureData into an image.NRGBA.
|
// Image converts PictureData into an image.RGBA.
|
||||||
//
|
//
|
||||||
// The resulting image.NRGBA's Bounds will be equivalent of the PictureData's Bounds.
|
// The resulting image.RGBA's Bounds will be equivalent of the PictureData's Bounds.
|
||||||
func (pd *PictureData) Image() *image.NRGBA {
|
func (pd *PictureData) Image() *image.RGBA {
|
||||||
bounds := image.Rect(
|
bounds := image.Rect(
|
||||||
int(math.Floor(pd.Rect.Min.X())),
|
int(math.Floor(pd.Rect.Min.X())),
|
||||||
int(math.Floor(pd.Rect.Min.Y())),
|
int(math.Floor(pd.Rect.Min.Y())),
|
||||||
int(math.Ceil(pd.Rect.Max.X())),
|
int(math.Ceil(pd.Rect.Max.X())),
|
||||||
int(math.Ceil(pd.Rect.Max.Y())),
|
int(math.Ceil(pd.Rect.Max.Y())),
|
||||||
)
|
)
|
||||||
nrgba := image.NewNRGBA(bounds)
|
rgba := image.NewRGBA(bounds)
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
||||||
for x := bounds.Min.X; x < bounds.Max.X; x++ {
|
for x := bounds.Min.X; x < bounds.Max.X; x++ {
|
||||||
off := pd.Index(V(float64(x), float64(y)))
|
off := pd.Index(V(float64(x), float64(y)))
|
||||||
nrgba.Pix[i*4+0] = pd.Pix[off].R
|
rgba.Pix[i*4+0] = pd.Pix[off].R
|
||||||
nrgba.Pix[i*4+1] = pd.Pix[off].G
|
rgba.Pix[i*4+1] = pd.Pix[off].G
|
||||||
nrgba.Pix[i*4+2] = pd.Pix[off].B
|
rgba.Pix[i*4+2] = pd.Pix[off].B
|
||||||
nrgba.Pix[i*4+3] = pd.Pix[off].A
|
rgba.Pix[i*4+3] = pd.Pix[off].A
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verticalFlip(nrgba)
|
verticalFlip(rgba)
|
||||||
|
|
||||||
return nrgba
|
return rgba
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index returns the index of the pixel at the specified position inside the Pix slice.
|
// Index returns the index of the pixel at the specified position inside the Pix slice.
|
||||||
|
@ -262,11 +262,11 @@ func (pd *PictureData) Bounds() Rect {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color returns the color located at the given position.
|
// Color returns the color located at the given position.
|
||||||
func (pd *PictureData) Color(at Vec) NRGBA {
|
func (pd *PictureData) Color(at Vec) RGBA {
|
||||||
if !pd.Rect.Contains(at) {
|
if !pd.Rect.Contains(at) {
|
||||||
return NRGBA{0, 0, 0, 0}
|
return RGBA{0, 0, 0, 0}
|
||||||
}
|
}
|
||||||
return ToNRGBA(pd.Pix[pd.Index(at)])
|
return ToRGBA(pd.Pix[pd.Index(at)])
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetColor changes the color located at the given position.
|
// SetColor changes the color located at the given position.
|
||||||
|
@ -274,11 +274,11 @@ func (pd *PictureData) SetColor(at Vec, col color.Color) {
|
||||||
if !pd.Rect.Contains(at) {
|
if !pd.Rect.Contains(at) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nrgba := ToNRGBA(col)
|
rgba := ToRGBA(col)
|
||||||
pd.Pix[pd.Index(at)] = color.NRGBA{
|
pd.Pix[pd.Index(at)] = color.RGBA{
|
||||||
R: uint8(nrgba.R * 255),
|
R: uint8(rgba.R * 255),
|
||||||
G: uint8(nrgba.G * 255),
|
G: uint8(rgba.G * 255),
|
||||||
B: uint8(nrgba.B * 255),
|
B: uint8(rgba.B * 255),
|
||||||
A: uint8(nrgba.A * 255),
|
A: uint8(rgba.A * 255),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
//
|
//
|
||||||
// Use various methods to change properties of Pushed points:
|
// Use various methods to change properties of Pushed points:
|
||||||
//
|
//
|
||||||
// imd.Color(pixel.NRGBA{R: 1, G: 0, B: 0, A: 1})
|
// imd.Color(pixel.RGBA{R: 1, G: 0, B: 0, A: 1})
|
||||||
// imd.Push(pixel.V(200, 200))
|
// imd.Push(pixel.V(200, 200))
|
||||||
// imd.Circle(400, 0)
|
// imd.Circle(400, 0)
|
||||||
//
|
//
|
||||||
|
@ -46,7 +46,7 @@ type IMDraw struct {
|
||||||
points []point
|
points []point
|
||||||
opts point
|
opts point
|
||||||
matrix pixel.Matrix
|
matrix pixel.Matrix
|
||||||
mask pixel.NRGBA
|
mask pixel.RGBA
|
||||||
|
|
||||||
tri *pixel.TrianglesData
|
tri *pixel.TrianglesData
|
||||||
batch *pixel.Batch
|
batch *pixel.Batch
|
||||||
|
@ -56,7 +56,7 @@ var _ pixel.BasicTarget = (*IMDraw)(nil)
|
||||||
|
|
||||||
type point struct {
|
type point struct {
|
||||||
pos pixel.Vec
|
pos pixel.Vec
|
||||||
col pixel.NRGBA
|
col pixel.RGBA
|
||||||
pic pixel.Vec
|
pic pixel.Vec
|
||||||
in float64
|
in float64
|
||||||
precision int
|
precision int
|
||||||
|
@ -87,7 +87,7 @@ func New(pic pixel.Picture) *IMDraw {
|
||||||
batch: pixel.NewBatch(tri, pic),
|
batch: pixel.NewBatch(tri, pic),
|
||||||
}
|
}
|
||||||
im.SetMatrix(pixel.IM)
|
im.SetMatrix(pixel.IM)
|
||||||
im.SetColorMask(pixel.NRGBA{R: 1, G: 1, B: 1, A: 1})
|
im.SetColorMask(pixel.RGBA{R: 1, G: 1, B: 1, A: 1})
|
||||||
im.Reset()
|
im.Reset()
|
||||||
return im
|
return im
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ func (imd *IMDraw) pushPt(pos pixel.Vec, pt point) {
|
||||||
|
|
||||||
// Color sets the color of the next Pushed points.
|
// Color sets the color of the next Pushed points.
|
||||||
func (imd *IMDraw) Color(color color.Color) {
|
func (imd *IMDraw) Color(color color.Color) {
|
||||||
imd.opts.col = pixel.ToNRGBA(color)
|
imd.opts.col = pixel.ToRGBA(color)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Picture sets the Picture coordinates of the next Pushed points.
|
// Picture sets the Picture coordinates of the next Pushed points.
|
||||||
|
@ -160,7 +160,7 @@ func (imd *IMDraw) SetMatrix(m pixel.Matrix) {
|
||||||
|
|
||||||
// SetColorMask sets a color that all further point's color will be multiplied by.
|
// SetColorMask sets a color that all further point's color will be multiplied by.
|
||||||
func (imd *IMDraw) SetColorMask(color color.Color) {
|
func (imd *IMDraw) SetColorMask(color color.Color) {
|
||||||
imd.mask = pixel.ToNRGBA(color)
|
imd.mask = pixel.ToRGBA(color)
|
||||||
imd.batch.SetColorMask(imd.mask)
|
imd.batch.SetColorMask(imd.mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ type TrianglesPosition interface {
|
||||||
// TrianglesColor specifies Triangles with Color property.
|
// TrianglesColor specifies Triangles with Color property.
|
||||||
type TrianglesColor interface {
|
type TrianglesColor interface {
|
||||||
Triangles
|
Triangles
|
||||||
Color(i int) NRGBA
|
Color(i int) RGBA
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrianglesPicture specifies Triangles with Picture propery.
|
// TrianglesPicture specifies Triangles with Picture propery.
|
||||||
|
@ -126,8 +126,8 @@ type TargetPicture interface {
|
||||||
// PictureColor specifies Picture with Color property, so that every position inside the Picture's
|
// PictureColor specifies Picture with Color property, so that every position inside the Picture's
|
||||||
// Bounds has a color.
|
// Bounds has a color.
|
||||||
//
|
//
|
||||||
// Positions outside the Picture's Bounds must return transparent black (NRGBA{R: 0, G: 0, B: 0, A: 0}).
|
// Positions outside the Picture's Bounds must return full transparent (RGBA{R: 0, G: 0, B: 0, A: 0}).
|
||||||
type PictureColor interface {
|
type PictureColor interface {
|
||||||
Picture
|
Picture
|
||||||
Color(at Vec) NRGBA
|
Color(at Vec) RGBA
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,15 +95,15 @@ func (c *Canvas) SetMatrix(m pixel.Matrix) {
|
||||||
|
|
||||||
// SetColorMask sets a color that every color in triangles or a picture will be multiplied by.
|
// SetColorMask sets a color that every color in triangles or a picture will be multiplied by.
|
||||||
func (c *Canvas) SetColorMask(col color.Color) {
|
func (c *Canvas) SetColorMask(col color.Color) {
|
||||||
nrgba := pixel.NRGBA{R: 1, G: 1, B: 1, A: 1}
|
rgba := pixel.RGBA{R: 1, G: 1, B: 1, A: 1}
|
||||||
if col != nil {
|
if col != nil {
|
||||||
nrgba = pixel.ToNRGBA(col)
|
rgba = pixel.ToRGBA(col)
|
||||||
}
|
}
|
||||||
c.col = mgl32.Vec4{
|
c.col = mgl32.Vec4{
|
||||||
float32(nrgba.R),
|
float32(rgba.R),
|
||||||
float32(nrgba.G),
|
float32(rgba.G),
|
||||||
float32(nrgba.B),
|
float32(rgba.B),
|
||||||
float32(nrgba.A),
|
float32(rgba.A),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,10 +139,10 @@ func (c *Canvas) setGlhfBounds() {
|
||||||
func (c *Canvas) Clear(color color.Color) {
|
func (c *Canvas) Clear(color color.Color) {
|
||||||
c.gf.Dirty()
|
c.gf.Dirty()
|
||||||
|
|
||||||
nrgba := pixel.ToNRGBA(color)
|
rgba := pixel.ToRGBA(color)
|
||||||
|
|
||||||
// color masking
|
// color masking
|
||||||
nrgba = nrgba.Mul(pixel.NRGBA{
|
rgba = rgba.Mul(pixel.RGBA{
|
||||||
R: float64(c.col[0]),
|
R: float64(c.col[0]),
|
||||||
G: float64(c.col[1]),
|
G: float64(c.col[1]),
|
||||||
B: float64(c.col[2]),
|
B: float64(c.col[2]),
|
||||||
|
@ -153,17 +153,17 @@ func (c *Canvas) Clear(color color.Color) {
|
||||||
c.setGlhfBounds()
|
c.setGlhfBounds()
|
||||||
c.gf.Frame().Begin()
|
c.gf.Frame().Begin()
|
||||||
glhf.Clear(
|
glhf.Clear(
|
||||||
float32(nrgba.R),
|
float32(rgba.R),
|
||||||
float32(nrgba.G),
|
float32(rgba.G),
|
||||||
float32(nrgba.B),
|
float32(rgba.B),
|
||||||
float32(nrgba.A),
|
float32(rgba.A),
|
||||||
)
|
)
|
||||||
c.gf.Frame().End()
|
c.gf.Frame().End()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color returns the color of the pixel over the given position inside the Canvas.
|
// Color returns the color of the pixel over the given position inside the Canvas.
|
||||||
func (c *Canvas) Color(at pixel.Vec) pixel.NRGBA {
|
func (c *Canvas) Color(at pixel.Vec) pixel.RGBA {
|
||||||
return c.gf.Color(at)
|
return c.gf.Color(at)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,9 +324,10 @@ void main() {
|
||||||
color = colorMask * Color;
|
color = colorMask * Color;
|
||||||
} else {
|
} else {
|
||||||
color = vec4(0, 0, 0, 0);
|
color = vec4(0, 0, 0, 0);
|
||||||
color += (1 - Intensity) * colorMask * Color;
|
color += (1 - Intensity) * Color;
|
||||||
vec2 t = (Texture - texBounds.xy) / texBounds.zw;
|
vec2 t = (Texture - texBounds.xy) / texBounds.zw;
|
||||||
color += Intensity * colorMask * Color * texture(tex, t);
|
color += Intensity * Color * texture(tex, t);
|
||||||
|
color *= colorMask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
|
@ -56,7 +56,7 @@ func (gf *GLFrame) Bounds() pixel.Rect {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color returns the color of the pixel under the specified position.
|
// Color returns the color of the pixel under the specified position.
|
||||||
func (gf *GLFrame) Color(at pixel.Vec) pixel.NRGBA {
|
func (gf *GLFrame) Color(at pixel.Vec) pixel.RGBA {
|
||||||
if gf.dirty {
|
if gf.dirty {
|
||||||
mainthread.Call(func() {
|
mainthread.Call(func() {
|
||||||
tex := gf.frame.Texture()
|
tex := gf.frame.Texture()
|
||||||
|
@ -67,12 +67,12 @@ func (gf *GLFrame) Color(at pixel.Vec) pixel.NRGBA {
|
||||||
gf.dirty = false
|
gf.dirty = false
|
||||||
}
|
}
|
||||||
if !gf.bounds.Contains(at) {
|
if !gf.bounds.Contains(at) {
|
||||||
return pixel.NRGBA{}
|
return pixel.RGBA{}
|
||||||
}
|
}
|
||||||
bx, by, bw, _ := intBounds(gf.bounds)
|
bx, by, bw, _ := intBounds(gf.bounds)
|
||||||
x, y := int(at.X())-bx, int(at.Y())-by
|
x, y := int(at.X())-bx, int(at.Y())-by
|
||||||
off := y*bw + x
|
off := y*bw + x
|
||||||
return pixel.NRGBA{
|
return pixel.RGBA{
|
||||||
R: float64(gf.pixels[off*4+0]) / 255,
|
R: float64(gf.pixels[off*4+0]) / 255,
|
||||||
G: float64(gf.pixels[off*4+1]) / 255,
|
G: float64(gf.pixels[off*4+1]) / 255,
|
||||||
B: float64(gf.pixels[off*4+2]) / 255,
|
B: float64(gf.pixels[off*4+2]) / 255,
|
||||||
|
|
|
@ -30,12 +30,12 @@ func NewGLPicture(p pixel.Picture) GLPicture {
|
||||||
// PictureData short path
|
// PictureData short path
|
||||||
for y := 0; y < bh; y++ {
|
for y := 0; y < bh; y++ {
|
||||||
for x := 0; x < bw; x++ {
|
for x := 0; x < bw; x++ {
|
||||||
nrgba := pd.Pix[y*pd.Stride+x]
|
rgba := pd.Pix[y*pd.Stride+x]
|
||||||
off := (y*bw + x) * 4
|
off := (y*bw + x) * 4
|
||||||
pixels[off+0] = nrgba.R
|
pixels[off+0] = rgba.R
|
||||||
pixels[off+1] = nrgba.G
|
pixels[off+1] = rgba.G
|
||||||
pixels[off+2] = nrgba.B
|
pixels[off+2] = rgba.B
|
||||||
pixels[off+3] = nrgba.A
|
pixels[off+3] = rgba.A
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if p, ok := p.(pixel.PictureColor); ok {
|
} else if p, ok := p.(pixel.PictureColor); ok {
|
||||||
|
@ -82,14 +82,14 @@ func (gp *glPicture) Texture() *glhf.Texture {
|
||||||
return gp.tex
|
return gp.tex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gp *glPicture) Color(at pixel.Vec) pixel.NRGBA {
|
func (gp *glPicture) Color(at pixel.Vec) pixel.RGBA {
|
||||||
if !gp.bounds.Contains(at) {
|
if !gp.bounds.Contains(at) {
|
||||||
return pixel.NRGBA{}
|
return pixel.RGBA{}
|
||||||
}
|
}
|
||||||
bx, by, bw, _ := intBounds(gp.bounds)
|
bx, by, bw, _ := intBounds(gp.bounds)
|
||||||
x, y := int(at.X())-bx, int(at.Y())-by
|
x, y := int(at.X())-bx, int(at.Y())-by
|
||||||
off := y*bw + x
|
off := y*bw + x
|
||||||
return pixel.NRGBA{
|
return pixel.RGBA{
|
||||||
R: float64(gp.pixels[off*4+0]) / 255,
|
R: float64(gp.pixels[off*4+0]) / 255,
|
||||||
G: float64(gp.pixels[off*4+1]) / 255,
|
G: float64(gp.pixels[off*4+1]) / 255,
|
||||||
B: float64(gp.pixels[off*4+2]) / 255,
|
B: float64(gp.pixels[off*4+2]) / 255,
|
||||||
|
|
|
@ -178,12 +178,12 @@ func (gt *GLTriangles) Position(i int) pixel.Vec {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color returns the Color property of the i-th vertex.
|
// Color returns the Color property of the i-th vertex.
|
||||||
func (gt *GLTriangles) Color(i int) pixel.NRGBA {
|
func (gt *GLTriangles) Color(i int) pixel.RGBA {
|
||||||
r := gt.data[i*gt.vs.Stride()+2]
|
r := gt.data[i*gt.vs.Stride()+2]
|
||||||
g := gt.data[i*gt.vs.Stride()+3]
|
g := gt.data[i*gt.vs.Stride()+3]
|
||||||
b := gt.data[i*gt.vs.Stride()+4]
|
b := gt.data[i*gt.vs.Stride()+4]
|
||||||
a := gt.data[i*gt.vs.Stride()+5]
|
a := gt.data[i*gt.vs.Stride()+5]
|
||||||
return pixel.NRGBA{
|
return pixel.RGBA{
|
||||||
R: float64(r),
|
R: float64(r),
|
||||||
G: float64(g),
|
G: float64(g),
|
||||||
B: float64(b),
|
B: float64(b),
|
||||||
|
|
|
@ -399,6 +399,6 @@ func (w *Window) Clear(c color.Color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color returns the color of the pixel over the given position inside the Window.
|
// Color returns the color of the pixel over the given position inside the Window.
|
||||||
func (w *Window) Color(at pixel.Vec) pixel.NRGBA {
|
func (w *Window) Color(at pixel.Vec) pixel.RGBA {
|
||||||
return w.canvas.Color(at)
|
return w.canvas.Color(at)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ type Sprite struct {
|
||||||
d Drawer
|
d Drawer
|
||||||
|
|
||||||
matrix Matrix
|
matrix Matrix
|
||||||
mask NRGBA
|
mask RGBA
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSprite creates a Sprite from the supplied frame of a Picture.
|
// NewSprite creates a Sprite from the supplied frame of a Picture.
|
||||||
|
@ -28,7 +28,7 @@ func NewSprite(pic Picture, frame Rect) *Sprite {
|
||||||
d: Drawer{Triangles: tri},
|
d: Drawer{Triangles: tri},
|
||||||
}
|
}
|
||||||
s.matrix = IM
|
s.matrix = IM
|
||||||
s.mask = NRGBA{1, 1, 1, 1}
|
s.mask = RGBA{1, 1, 1, 1}
|
||||||
s.Set(pic, frame)
|
s.Set(pic, frame)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
@ -73,12 +73,12 @@ func (s *Sprite) Matrix() Matrix {
|
||||||
// Note, that this has nothing to do with BasicTarget's SetColorMask method. This only affects this
|
// Note, that this has nothing to do with BasicTarget's SetColorMask method. This only affects this
|
||||||
// Sprite and is usable with any Target.
|
// Sprite and is usable with any Target.
|
||||||
func (s *Sprite) SetColorMask(mask color.Color) {
|
func (s *Sprite) SetColorMask(mask color.Color) {
|
||||||
s.mask = ToNRGBA(mask)
|
s.mask = ToRGBA(mask)
|
||||||
s.calcData()
|
s.calcData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColorMask returns the currently set color mask.
|
// ColorMask returns the currently set color mask.
|
||||||
func (s *Sprite) ColorMask() NRGBA {
|
func (s *Sprite) ColorMask() RGBA {
|
||||||
return s.mask
|
return s.mask
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue