diff --git a/batch.go b/batch.go index 63f6849..452f17e 100644 --- a/batch.go +++ b/batch.go @@ -13,7 +13,7 @@ type Batch struct { cont Drawer mat Matrix - col NRGBA + col RGBA } var _ BasicTarget = (*Batch)(nil) @@ -28,7 +28,7 @@ var _ BasicTarget = (*Batch)(nil) func NewBatch(container Triangles, pic Picture) *Batch { b := &Batch{cont: Drawer{Triangles: container, Picture: pic}} b.SetMatrix(IM) - b.SetColorMask(NRGBA{1, 1, 1, 1}) + b.SetColorMask(RGBA{1, 1, 1, 1}) 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. func (b *Batch) SetColorMask(c color.Color) { if c == nil { - b.col = NRGBA{1, 1, 1, 1} + b.col = RGBA{1, 1, 1, 1} return } - b.col = ToNRGBA(c) + b.col = ToRGBA(c) } // MakeTriangles returns a specialized copy of the provided Triangles that draws onto this Batch. diff --git a/color.go b/color.go index 45d424c..46e6c30 100644 --- a/color.go +++ b/color.go @@ -2,17 +2,17 @@ package pixel 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. -type NRGBA struct { +// The difference between color.RGBA is that the value range is [0, 1] and the values are floats. +type RGBA struct { R, G, B, A float64 } // Add adds color d to color c component-wise and returns the result (the components are not // clamped). -func (c NRGBA) Add(d NRGBA) NRGBA { - return NRGBA{ +func (c RGBA) Add(d RGBA) RGBA { + return RGBA{ R: c.R + d.R, G: c.G + d.G, 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 // are not clamped). -func (c NRGBA) Sub(d NRGBA) NRGBA { - return NRGBA{ +func (c RGBA) Sub(d RGBA) RGBA { + return RGBA{ R: c.R - d.R, G: c.G - d.G, 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). -func (c NRGBA) Mul(d NRGBA) NRGBA { - return NRGBA{ +func (c RGBA) Mul(d RGBA) RGBA { + return RGBA{ R: c.R * d.R, G: c.G * d.G, 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 // are not clamped). -func (c NRGBA) Scaled(scale float64) NRGBA { - return NRGBA{ +func (c RGBA) Scaled(scale float64) RGBA { + return RGBA{ R: c.R * scale, G: c.G * 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. -func (c NRGBA) RGBA() (r, g, b, a uint32) { - c.R = clamp(c.R, 0, 1) - c.G = clamp(c.G, 0, 1) - c.B = clamp(c.B, 0, 1) - 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) +// RGBA returns alpha-premultiplied red, green, blue and alpha components of the RGBA color. +func (c RGBA) RGBA() (r, g, b, a uint32) { + r = uint32(0xffff * c.R) + g = uint32(0xffff * c.G) + b = uint32(0xffff * c.B) a = uint32(0xffff * c.A) return } -func clamp(x, low, high float64) float64 { - if x < low { - return low - } - 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 { +// ToRGBA converts a color to RGBA format. Using this function is preferred to using RGBAModel, for +// performance (using RGBAModel introduced additional unnecessary allocations). +func ToRGBA(c color.Color) RGBA { + if c, ok := c.(RGBA); ok { return c } - if c, ok := c.(color.NRGBA); ok { - return NRGBA{ + if c, ok := c.(color.RGBA); ok { + return RGBA{ R: float64(c.R) / 255, G: float64(c.G) / 255, B: float64(c.B) / 255, @@ -90,20 +76,17 @@ func ToNRGBA(c color.Color) NRGBA { } } r, g, b, a := c.RGBA() - if a == 0 { - return NRGBA{0, 0, 0, 0} - } - return NRGBA{ - float64(r) / float64(a), - float64(g) / float64(a), - float64(b) / float64(a), + return RGBA{ + float64(r) / 0xffff, + float64(g) / 0xffff, + float64(b) / 0xffff, float64(a) / 0xffff, } } -// NRGBAModel converts colors to NRGBA format. -var NRGBAModel = color.ModelFunc(nrgbaModel) +// RGBAModel converts colors to RGBA format. +var RGBAModel = color.ModelFunc(rgbaModel) -func nrgbaModel(c color.Color) color.Color { - return ToNRGBA(c) +func rgbaModel(c color.Color) color.Color { + return ToRGBA(c) } diff --git a/data.go b/data.go index 8263693..7d21d49 100644 --- a/data.go +++ b/data.go @@ -12,7 +12,7 @@ import ( // TrianglesPosition, TrianglesColor and TrianglesPicture. type TrianglesData []struct { Position Vec - Color NRGBA + Color RGBA Picture Vec Intensity float64 } @@ -42,10 +42,10 @@ func (td *TrianglesData) SetLen(len int) { for i := 0; i < needAppend; i++ { *td = append(*td, struct { Position Vec - Color NRGBA + Color RGBA Picture Vec 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() { @@ -108,7 +108,7 @@ func (td *TrianglesData) Position(i int) Vec { } // 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 } @@ -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 format of the pixels is color.NRGBA and not pixel.NRGBA for a very serious reason: -// pixel.NRGBA takes up 8x more memory than color.NRGBA. +// The format of the pixels is color.RGBA and not pixel.RGBA for a very serious reason: +// pixel.RGBA takes up 8x more memory than color.RGBA. type PictureData struct { - Pix []color.NRGBA + Pix []color.RGBA Stride int Rect Rect } @@ -142,18 +142,18 @@ func MakePictureData(rect Rect) *PictureData { Stride: w, Rect: rect, } - pd.Pix = make([]color.NRGBA, w*h) + pd.Pix = make([]color.RGBA, w*h) return pd } -func verticalFlip(nrgba *image.NRGBA) { - bounds := nrgba.Bounds() +func verticalFlip(rgba *image.RGBA) { + bounds := rgba.Bounds() width := bounds.Dx() tmpRow := make([]uint8, width*4) 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] - jRow := nrgba.Pix[j*nrgba.Stride : j*nrgba.Stride+width*4] + iRow := rgba.Pix[i*rgba.Stride : i*rgba.Stride+width*4] + jRow := rgba.Pix[j*rgba.Stride : j*rgba.Stride+width*4] copy(tmpRow, iRow) 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. func PictureDataFromImage(img image.Image) *PictureData { - var nrgba *image.NRGBA - if nrgbaImg, ok := img.(*image.NRGBA); ok { - nrgba = nrgbaImg + var rgba *image.RGBA + if rgbaImg, ok := img.(*image.RGBA); ok { + rgba = rgbaImg } else { - nrgba = image.NewNRGBA(img.Bounds()) - draw.Draw(nrgba, nrgba.Bounds(), img, img.Bounds().Min, draw.Src) + rgba = image.NewRGBA(img.Bounds()) + draw.Draw(rgba, rgba.Bounds(), img, img.Bounds().Min, draw.Src) } - verticalFlip(nrgba) + verticalFlip(rgba) pd := MakePictureData(R( - float64(nrgba.Bounds().Min.X), - float64(nrgba.Bounds().Min.Y), - float64(nrgba.Bounds().Dx()), - float64(nrgba.Bounds().Dy()), + float64(rgba.Bounds().Min.X), + float64(rgba.Bounds().Min.Y), + float64(rgba.Bounds().Dx()), + float64(rgba.Bounds().Dy()), )) for i := range pd.Pix { - pd.Pix[i].R = nrgba.Pix[i*4+0] - pd.Pix[i].G = nrgba.Pix[i*4+1] - pd.Pix[i].B = nrgba.Pix[i*4+2] - pd.Pix[i].A = nrgba.Pix[i*4+3] + pd.Pix[i].R = rgba.Pix[i*4+0] + pd.Pix[i].G = rgba.Pix[i*4+1] + pd.Pix[i].B = rgba.Pix[i*4+2] + pd.Pix[i].A = rgba.Pix[i*4+3] } return pd @@ -220,33 +220,33 @@ func PictureDataFromPicture(pic Picture) *PictureData { 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. -func (pd *PictureData) Image() *image.NRGBA { +// The resulting image.RGBA's Bounds will be equivalent of the PictureData's Bounds. +func (pd *PictureData) Image() *image.RGBA { bounds := image.Rect( int(math.Floor(pd.Rect.Min.X())), int(math.Floor(pd.Rect.Min.Y())), int(math.Ceil(pd.Rect.Max.X())), int(math.Ceil(pd.Rect.Max.Y())), ) - nrgba := image.NewNRGBA(bounds) + rgba := image.NewRGBA(bounds) i := 0 for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { off := pd.Index(V(float64(x), float64(y))) - nrgba.Pix[i*4+0] = pd.Pix[off].R - nrgba.Pix[i*4+1] = pd.Pix[off].G - nrgba.Pix[i*4+2] = pd.Pix[off].B - nrgba.Pix[i*4+3] = pd.Pix[off].A + rgba.Pix[i*4+0] = pd.Pix[off].R + rgba.Pix[i*4+1] = pd.Pix[off].G + rgba.Pix[i*4+2] = pd.Pix[off].B + rgba.Pix[i*4+3] = pd.Pix[off].A i++ } } - verticalFlip(nrgba) + verticalFlip(rgba) - return nrgba + return rgba } // 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. -func (pd *PictureData) Color(at Vec) NRGBA { +func (pd *PictureData) Color(at Vec) RGBA { 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. @@ -274,11 +274,11 @@ func (pd *PictureData) SetColor(at Vec, col color.Color) { if !pd.Rect.Contains(at) { return } - nrgba := ToNRGBA(col) - pd.Pix[pd.Index(at)] = color.NRGBA{ - R: uint8(nrgba.R * 255), - G: uint8(nrgba.G * 255), - B: uint8(nrgba.B * 255), - A: uint8(nrgba.A * 255), + rgba := ToRGBA(col) + pd.Pix[pd.Index(at)] = color.RGBA{ + R: uint8(rgba.R * 255), + G: uint8(rgba.G * 255), + B: uint8(rgba.B * 255), + A: uint8(rgba.A * 255), } } diff --git a/imdraw/imdraw.go b/imdraw/imdraw.go index 39ac87e..98e9325 100644 --- a/imdraw/imdraw.go +++ b/imdraw/imdraw.go @@ -23,7 +23,7 @@ import ( // // 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.Circle(400, 0) // @@ -46,7 +46,7 @@ type IMDraw struct { points []point opts point matrix pixel.Matrix - mask pixel.NRGBA + mask pixel.RGBA tri *pixel.TrianglesData batch *pixel.Batch @@ -56,7 +56,7 @@ var _ pixel.BasicTarget = (*IMDraw)(nil) type point struct { pos pixel.Vec - col pixel.NRGBA + col pixel.RGBA pic pixel.Vec in float64 precision int @@ -87,7 +87,7 @@ func New(pic pixel.Picture) *IMDraw { batch: pixel.NewBatch(tri, pic), } 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() return im } @@ -127,7 +127,7 @@ func (imd *IMDraw) pushPt(pos pixel.Vec, pt point) { // Color sets the color of the next Pushed points. 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. @@ -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. func (imd *IMDraw) SetColorMask(color color.Color) { - imd.mask = pixel.ToNRGBA(color) + imd.mask = pixel.ToRGBA(color) imd.batch.SetColorMask(imd.mask) } diff --git a/interface.go b/interface.go index 8f0f824..5f48f65 100644 --- a/interface.go +++ b/interface.go @@ -89,7 +89,7 @@ type TrianglesPosition interface { // TrianglesColor specifies Triangles with Color property. type TrianglesColor interface { Triangles - Color(i int) NRGBA + Color(i int) RGBA } // 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 // 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 { Picture - Color(at Vec) NRGBA + Color(at Vec) RGBA } diff --git a/pixelgl/canvas.go b/pixelgl/canvas.go index 9a773e8..53b2b0e 100644 --- a/pixelgl/canvas.go +++ b/pixelgl/canvas.go @@ -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. 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 { - nrgba = pixel.ToNRGBA(col) + rgba = pixel.ToRGBA(col) } c.col = mgl32.Vec4{ - float32(nrgba.R), - float32(nrgba.G), - float32(nrgba.B), - float32(nrgba.A), + float32(rgba.R), + float32(rgba.G), + float32(rgba.B), + float32(rgba.A), } } @@ -139,10 +139,10 @@ func (c *Canvas) setGlhfBounds() { func (c *Canvas) Clear(color color.Color) { c.gf.Dirty() - nrgba := pixel.ToNRGBA(color) + rgba := pixel.ToRGBA(color) // color masking - nrgba = nrgba.Mul(pixel.NRGBA{ + rgba = rgba.Mul(pixel.RGBA{ R: float64(c.col[0]), G: float64(c.col[1]), B: float64(c.col[2]), @@ -153,17 +153,17 @@ func (c *Canvas) Clear(color color.Color) { c.setGlhfBounds() c.gf.Frame().Begin() glhf.Clear( - float32(nrgba.R), - float32(nrgba.G), - float32(nrgba.B), - float32(nrgba.A), + float32(rgba.R), + float32(rgba.G), + float32(rgba.B), + float32(rgba.A), ) c.gf.Frame().End() }) } // 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) } @@ -324,9 +324,10 @@ void main() { color = colorMask * Color; } else { color = vec4(0, 0, 0, 0); - color += (1 - Intensity) * colorMask * Color; + color += (1 - Intensity) * Color; vec2 t = (Texture - texBounds.xy) / texBounds.zw; - color += Intensity * colorMask * Color * texture(tex, t); + color += Intensity * Color * texture(tex, t); + color *= colorMask; } } ` diff --git a/pixelgl/glframe.go b/pixelgl/glframe.go index 7eac7a1..a525b81 100644 --- a/pixelgl/glframe.go +++ b/pixelgl/glframe.go @@ -56,7 +56,7 @@ func (gf *GLFrame) Bounds() pixel.Rect { } // 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 { mainthread.Call(func() { tex := gf.frame.Texture() @@ -67,12 +67,12 @@ func (gf *GLFrame) Color(at pixel.Vec) pixel.NRGBA { gf.dirty = false } if !gf.bounds.Contains(at) { - return pixel.NRGBA{} + return pixel.RGBA{} } bx, by, bw, _ := intBounds(gf.bounds) x, y := int(at.X())-bx, int(at.Y())-by off := y*bw + x - return pixel.NRGBA{ + return pixel.RGBA{ R: float64(gf.pixels[off*4+0]) / 255, G: float64(gf.pixels[off*4+1]) / 255, B: float64(gf.pixels[off*4+2]) / 255, diff --git a/pixelgl/glpicture.go b/pixelgl/glpicture.go index bb4b2f4..b5793ec 100644 --- a/pixelgl/glpicture.go +++ b/pixelgl/glpicture.go @@ -30,12 +30,12 @@ func NewGLPicture(p pixel.Picture) GLPicture { // PictureData short path for y := 0; y < bh; y++ { 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 - pixels[off+0] = nrgba.R - pixels[off+1] = nrgba.G - pixels[off+2] = nrgba.B - pixels[off+3] = nrgba.A + pixels[off+0] = rgba.R + pixels[off+1] = rgba.G + pixels[off+2] = rgba.B + pixels[off+3] = rgba.A } } } else if p, ok := p.(pixel.PictureColor); ok { @@ -82,14 +82,14 @@ func (gp *glPicture) Texture() *glhf.Texture { 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) { - return pixel.NRGBA{} + return pixel.RGBA{} } bx, by, bw, _ := intBounds(gp.bounds) x, y := int(at.X())-bx, int(at.Y())-by off := y*bw + x - return pixel.NRGBA{ + return pixel.RGBA{ R: float64(gp.pixels[off*4+0]) / 255, G: float64(gp.pixels[off*4+1]) / 255, B: float64(gp.pixels[off*4+2]) / 255, diff --git a/pixelgl/gltriangles.go b/pixelgl/gltriangles.go index 73142f6..12d05f4 100644 --- a/pixelgl/gltriangles.go +++ b/pixelgl/gltriangles.go @@ -178,12 +178,12 @@ func (gt *GLTriangles) Position(i int) pixel.Vec { } // 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] g := gt.data[i*gt.vs.Stride()+3] b := gt.data[i*gt.vs.Stride()+4] a := gt.data[i*gt.vs.Stride()+5] - return pixel.NRGBA{ + return pixel.RGBA{ R: float64(r), G: float64(g), B: float64(b), diff --git a/pixelgl/window.go b/pixelgl/window.go index 33a3fe1..c998359 100644 --- a/pixelgl/window.go +++ b/pixelgl/window.go @@ -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. -func (w *Window) Color(at pixel.Vec) pixel.NRGBA { +func (w *Window) Color(at pixel.Vec) pixel.RGBA { return w.canvas.Color(at) } diff --git a/sprite.go b/sprite.go index d7f34a8..c438663 100644 --- a/sprite.go +++ b/sprite.go @@ -17,7 +17,7 @@ type Sprite struct { d Drawer matrix Matrix - mask NRGBA + mask RGBA } // 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}, } s.matrix = IM - s.mask = NRGBA{1, 1, 1, 1} + s.mask = RGBA{1, 1, 1, 1} s.Set(pic, frame) 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 // Sprite and is usable with any Target. func (s *Sprite) SetColorMask(mask color.Color) { - s.mask = ToNRGBA(mask) + s.mask = ToRGBA(mask) s.calcData() } // ColorMask returns the currently set color mask. -func (s *Sprite) ColorMask() NRGBA { +func (s *Sprite) ColorMask() RGBA { return s.mask }