replace NRGBA to RGBA because Porter-Duff (!!!)

This commit is contained in:
faiface 2017-04-09 22:00:26 +02:00
parent 7d31dd8d6f
commit f4916a4272
11 changed files with 122 additions and 138 deletions

View File

@ -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.

View File

@ -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
View File

@ -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),
} }
} }

View File

@ -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)
} }

View File

@ -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
} }

View File

@ -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;
} }
} }
` `

View File

@ -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,

View File

@ -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,

View File

@ -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),

View File

@ -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)
} }

View File

@ -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
} }