mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
parent
8144c9d638
commit
5a9235aaf9
4
image.go
4
image.go
@ -238,9 +238,9 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a, b, c, d, tx, ty := geom.elements()
|
a, b, c, d, tx, ty := geom.elements()
|
||||||
vs := img.shareableImage.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty)
|
vs := img.shareableImage.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, options.ColorM.impl)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
i.shareableImage.DrawImage(img.shareableImage, vs, is, options.ColorM.impl, mode, filter)
|
i.shareableImage.DrawImage(img.shareableImage, vs, is, mode, filter)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,48 +139,6 @@ func (c *ColorM) SetElement(i, j int, element float32) *ColorM {
|
|||||||
return newC
|
return newC
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ColorM) Equals(other *ColorM) bool {
|
|
||||||
if !c.isInited() && !other.isInited() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
lhsb := colorMIdentityBody
|
|
||||||
lhst := colorMIdentityTranslate
|
|
||||||
rhsb := colorMIdentityBody
|
|
||||||
rhst := colorMIdentityTranslate
|
|
||||||
if other.isInited() {
|
|
||||||
if other.body != nil {
|
|
||||||
lhsb = other.body
|
|
||||||
}
|
|
||||||
if other.translate != nil {
|
|
||||||
lhst = other.translate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if c.isInited() {
|
|
||||||
if c.body != nil {
|
|
||||||
rhsb = c.body
|
|
||||||
}
|
|
||||||
if c.translate != nil {
|
|
||||||
rhst = c.translate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if &lhsb == &rhsb && &lhst == &rhst {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range lhsb {
|
|
||||||
if lhsb[i] != rhsb[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := range lhst {
|
|
||||||
if lhst[i] != rhst[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Concat multiplies a color matrix with the other color matrix.
|
// Concat multiplies a color matrix with the other color matrix.
|
||||||
// This is same as muptiplying the matrix other and the matrix c in this order.
|
// This is same as muptiplying the matrix other and the matrix c in this order.
|
||||||
func (c *ColorM) Concat(other *ColorM) *ColorM {
|
func (c *ColorM) Concat(other *ColorM) *ColorM {
|
||||||
|
@ -17,7 +17,6 @@ package graphics
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/affine"
|
|
||||||
emath "github.com/hajimehoshi/ebiten/internal/math"
|
emath "github.com/hajimehoshi/ebiten/internal/math"
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
)
|
)
|
||||||
@ -34,7 +33,7 @@ type command interface {
|
|||||||
NumIndices() int
|
NumIndices() int
|
||||||
AddNumVertices(n int)
|
AddNumVertices(n int)
|
||||||
AddNumIndices(n int)
|
AddNumIndices(n int)
|
||||||
CanMerge(dst, src *Image, color *affine.ColorM, mode opengl.CompositeMode, filter Filter) bool
|
CanMerge(dst, src *Image, mode opengl.CompositeMode, filter Filter) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// commandQueue is a command queue for drawing commands.
|
// commandQueue is a command queue for drawing commands.
|
||||||
@ -86,12 +85,12 @@ func (q *commandQueue) appendIndices(indices []uint16, offset uint16) {
|
|||||||
q.nindices += len(indices)
|
q.nindices += len(indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nindices int, color *affine.ColorM, mode opengl.CompositeMode, filter Filter, forceNewCommand bool) {
|
func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nindices int, mode opengl.CompositeMode, filter Filter, forceNewCommand bool) {
|
||||||
if nindices > indicesNum {
|
if nindices > indicesNum {
|
||||||
panic("not implemented for too many indices")
|
panic("not implemented for too many indices")
|
||||||
}
|
}
|
||||||
if !forceNewCommand && 0 < len(q.commands) {
|
if !forceNewCommand && 0 < len(q.commands) {
|
||||||
if last := q.commands[len(q.commands)-1]; last.CanMerge(dst, src, color, mode, filter) {
|
if last := q.commands[len(q.commands)-1]; last.CanMerge(dst, src, mode, filter) {
|
||||||
last.AddNumVertices(nvertices)
|
last.AddNumVertices(nvertices)
|
||||||
last.AddNumIndices(nindices)
|
last.AddNumIndices(nindices)
|
||||||
return
|
return
|
||||||
@ -102,7 +101,6 @@ func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nin
|
|||||||
src: src,
|
src: src,
|
||||||
nvertices: nvertices,
|
nvertices: nvertices,
|
||||||
nindices: nindices,
|
nindices: nindices,
|
||||||
color: color,
|
|
||||||
mode: mode,
|
mode: mode,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
}
|
}
|
||||||
@ -110,7 +108,7 @@ func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EnqueueDrawImageCommand enqueues a drawing-image command.
|
// EnqueueDrawImageCommand enqueues a drawing-image command.
|
||||||
func (q *commandQueue) EnqueueDrawImageCommand(dst, src *Image, vertices []float32, indices []uint16, color *affine.ColorM, mode opengl.CompositeMode, filter Filter) {
|
func (q *commandQueue) EnqueueDrawImageCommand(dst, src *Image, vertices []float32, indices []uint16, mode opengl.CompositeMode, filter Filter) {
|
||||||
if len(indices) > indicesNum {
|
if len(indices) > indicesNum {
|
||||||
panic("not reached")
|
panic("not reached")
|
||||||
}
|
}
|
||||||
@ -127,7 +125,7 @@ func (q *commandQueue) EnqueueDrawImageCommand(dst, src *Image, vertices []float
|
|||||||
q.nextIndex += len(vertices) * opengl.Float.SizeInBytes() / VertexSizeInBytes()
|
q.nextIndex += len(vertices) * opengl.Float.SizeInBytes() / VertexSizeInBytes()
|
||||||
q.tmpNumIndices += len(indices)
|
q.tmpNumIndices += len(indices)
|
||||||
|
|
||||||
q.doEnqueueDrawImageCommand(dst, src, len(vertices), len(indices), color, mode, filter, split)
|
q.doEnqueueDrawImageCommand(dst, src, len(vertices), len(indices), mode, filter, split)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue enqueues a drawing command other than a draw-image command.
|
// Enqueue enqueues a drawing command other than a draw-image command.
|
||||||
@ -211,7 +209,6 @@ type drawImageCommand struct {
|
|||||||
src *Image
|
src *Image
|
||||||
nvertices int
|
nvertices int
|
||||||
nindices int
|
nindices int
|
||||||
color *affine.ColorM
|
|
||||||
mode opengl.CompositeMode
|
mode opengl.CompositeMode
|
||||||
filter Filter
|
filter Filter
|
||||||
}
|
}
|
||||||
@ -235,7 +232,7 @@ func (c *drawImageCommand) Exec(indexOffsetInBytes int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
proj := f.projectionMatrix()
|
proj := f.projectionMatrix()
|
||||||
theOpenGLState.useProgram(proj, c.src.texture.native, c.dst, c.src, c.color, c.filter)
|
theOpenGLState.useProgram(proj, c.src.texture.native, c.dst, c.src, c.filter)
|
||||||
opengl.GetContext().DrawElements(opengl.Triangles, c.nindices, indexOffsetInBytes)
|
opengl.GetContext().DrawElements(opengl.Triangles, c.nindices, indexOffsetInBytes)
|
||||||
|
|
||||||
// glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419),
|
// glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419),
|
||||||
@ -263,16 +260,13 @@ func (c *drawImageCommand) AddNumIndices(n int) {
|
|||||||
|
|
||||||
// CanMerge returns a boolean value indicating whether the other drawImageCommand can be merged
|
// CanMerge returns a boolean value indicating whether the other drawImageCommand can be merged
|
||||||
// with the drawImageCommand c.
|
// with the drawImageCommand c.
|
||||||
func (c *drawImageCommand) CanMerge(dst, src *Image, color *affine.ColorM, mode opengl.CompositeMode, filter Filter) bool {
|
func (c *drawImageCommand) CanMerge(dst, src *Image, mode opengl.CompositeMode, filter Filter) bool {
|
||||||
if c.dst != dst {
|
if c.dst != dst {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if c.src != src {
|
if c.src != src {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !c.color.Equals(color) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if c.mode != mode {
|
if c.mode != mode {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -316,7 +310,7 @@ func (c *replacePixelsCommand) AddNumVertices(n int) {
|
|||||||
func (c *replacePixelsCommand) AddNumIndices(n int) {
|
func (c *replacePixelsCommand) AddNumIndices(n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *replacePixelsCommand) CanMerge(dst, src *Image, color *affine.ColorM, mode opengl.CompositeMode, filter Filter) bool {
|
func (c *replacePixelsCommand) CanMerge(dst, src *Image, mode opengl.CompositeMode, filter Filter) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +347,7 @@ func (c *pixelsCommand) AddNumVertices(n int) {
|
|||||||
func (c *pixelsCommand) AddNumIndices(n int) {
|
func (c *pixelsCommand) AddNumIndices(n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *pixelsCommand) CanMerge(dst, src *Image, color *affine.ColorM, mode opengl.CompositeMode, filter Filter) bool {
|
func (c *pixelsCommand) CanMerge(dst, src *Image, mode opengl.CompositeMode, filter Filter) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +382,7 @@ func (c *disposeCommand) AddNumVertices(n int) {
|
|||||||
func (c *disposeCommand) AddNumIndices(n int) {
|
func (c *disposeCommand) AddNumIndices(n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *disposeCommand) CanMerge(dst, src *Image, color *affine.ColorM, mode opengl.CompositeMode, filter Filter) bool {
|
func (c *disposeCommand) CanMerge(dst, src *Image, mode opengl.CompositeMode, filter Filter) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +438,7 @@ func (c *newImageCommand) AddNumVertices(n int) {
|
|||||||
func (c *newImageCommand) AddNumIndices(n int) {
|
func (c *newImageCommand) AddNumIndices(n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *newImageCommand) CanMerge(dst, src *Image, color *affine.ColorM, mode opengl.CompositeMode, filter Filter) bool {
|
func (c *newImageCommand) CanMerge(dst, src *Image, mode opengl.CompositeMode, filter Filter) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,6 +473,6 @@ func (c *newScreenFramebufferImageCommand) AddNumVertices(n int) {
|
|||||||
func (c *newScreenFramebufferImageCommand) AddNumIndices(n int) {
|
func (c *newScreenFramebufferImageCommand) AddNumIndices(n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *newScreenFramebufferImageCommand) CanMerge(dst, src *Image, color *affine.ColorM, mode opengl.CompositeMode, filter Filter) bool {
|
func (c *newScreenFramebufferImageCommand) CanMerge(dst, src *Image, mode opengl.CompositeMode, filter Filter) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
package graphics
|
package graphics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/internal/affine"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/math"
|
"github.com/hajimehoshi/ebiten/internal/math"
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
)
|
)
|
||||||
@ -86,8 +85,8 @@ func (i *Image) Size() (int, int) {
|
|||||||
return i.width, i.height
|
return i.width, i.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) DrawImage(src *Image, vertices []float32, indices []uint16, clr *affine.ColorM, mode opengl.CompositeMode, filter Filter) {
|
func (i *Image) DrawImage(src *Image, vertices []float32, indices []uint16, mode opengl.CompositeMode, filter Filter) {
|
||||||
theCommandQueue.EnqueueDrawImageCommand(i, src, vertices, indices, clr, mode, filter)
|
theCommandQueue.EnqueueDrawImageCommand(i, src, vertices, indices, mode, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pixels returns the image's pixels.
|
// Pixels returns the image's pixels.
|
||||||
|
@ -17,7 +17,6 @@ package graphics
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/affine"
|
|
||||||
emath "github.com/hajimehoshi/ebiten/internal/math"
|
emath "github.com/hajimehoshi/ebiten/internal/math"
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
"github.com/hajimehoshi/ebiten/internal/web"
|
"github.com/hajimehoshi/ebiten/internal/web"
|
||||||
@ -94,6 +93,31 @@ var (
|
|||||||
dataType: opengl.Float,
|
dataType: opengl.Float,
|
||||||
num: 4,
|
num: 4,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "color_body0",
|
||||||
|
dataType: opengl.Float,
|
||||||
|
num: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "color_body1",
|
||||||
|
dataType: opengl.Float,
|
||||||
|
num: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "color_body2",
|
||||||
|
dataType: opengl.Float,
|
||||||
|
num: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "color_body3",
|
||||||
|
dataType: opengl.Float,
|
||||||
|
num: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "color_translate",
|
||||||
|
dataType: opengl.Float,
|
||||||
|
num: 4,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -114,12 +138,10 @@ type openGLState struct {
|
|||||||
|
|
||||||
programScreen opengl.Program
|
programScreen opengl.Program
|
||||||
|
|
||||||
lastProgram opengl.Program
|
lastProgram opengl.Program
|
||||||
lastProjectionMatrix []float32
|
lastProjectionMatrix []float32
|
||||||
lastColorMatrix []float32
|
lastSourceWidth int
|
||||||
lastColorMatrixTranslation []float32
|
lastSourceHeight int
|
||||||
lastSourceWidth int
|
|
||||||
lastSourceHeight int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -149,8 +171,6 @@ func (s *openGLState) reset() error {
|
|||||||
|
|
||||||
s.lastProgram = zeroProgram
|
s.lastProgram = zeroProgram
|
||||||
s.lastProjectionMatrix = nil
|
s.lastProjectionMatrix = nil
|
||||||
s.lastColorMatrix = nil
|
|
||||||
s.lastColorMatrixTranslation = nil
|
|
||||||
s.lastSourceWidth = 0
|
s.lastSourceWidth = 0
|
||||||
s.lastSourceHeight = 0
|
s.lastSourceHeight = 0
|
||||||
|
|
||||||
@ -250,7 +270,7 @@ func areSameFloat32Array(a, b []float32) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// useProgram uses the program (programTexture).
|
// useProgram uses the program (programTexture).
|
||||||
func (s *openGLState) useProgram(proj []float32, texture opengl.Texture, dst, src *Image, colorM *affine.ColorM, filter Filter) {
|
func (s *openGLState) useProgram(proj []float32, texture opengl.Texture, dst, src *Image, filter Filter) {
|
||||||
c := opengl.GetContext()
|
c := opengl.GetContext()
|
||||||
|
|
||||||
var program opengl.Program
|
var program opengl.Program
|
||||||
@ -280,8 +300,6 @@ func (s *openGLState) useProgram(proj []float32, texture opengl.Texture, dst, sr
|
|||||||
|
|
||||||
s.lastProgram = program
|
s.lastProgram = program
|
||||||
s.lastProjectionMatrix = nil
|
s.lastProjectionMatrix = nil
|
||||||
s.lastColorMatrix = nil
|
|
||||||
s.lastColorMatrixTranslation = nil
|
|
||||||
s.lastSourceWidth = 0
|
s.lastSourceWidth = 0
|
||||||
s.lastSourceHeight = 0
|
s.lastSourceHeight = 0
|
||||||
}
|
}
|
||||||
@ -296,25 +314,6 @@ func (s *openGLState) useProgram(proj []float32, texture opengl.Texture, dst, sr
|
|||||||
s.lastProjectionMatrix = proj
|
s.lastProjectionMatrix = proj
|
||||||
}
|
}
|
||||||
|
|
||||||
esBody, esTranslate := colorM.UnsafeElements()
|
|
||||||
|
|
||||||
if !areSameFloat32Array(s.lastColorMatrix, esBody) {
|
|
||||||
c.UniformFloats(program, "color_matrix_body", esBody)
|
|
||||||
if s.lastColorMatrix == nil {
|
|
||||||
s.lastColorMatrix = make([]float32, 16)
|
|
||||||
}
|
|
||||||
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
|
||||||
s.lastColorMatrix = esBody
|
|
||||||
}
|
|
||||||
if !areSameFloat32Array(s.lastColorMatrixTranslation, esTranslate) {
|
|
||||||
c.UniformFloats(program, "color_matrix_translation", esTranslate)
|
|
||||||
if s.lastColorMatrixTranslation == nil {
|
|
||||||
s.lastColorMatrixTranslation = make([]float32, 4)
|
|
||||||
}
|
|
||||||
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
|
||||||
s.lastColorMatrixTranslation = esTranslate
|
|
||||||
}
|
|
||||||
|
|
||||||
sw, sh := src.Size()
|
sw, sh := src.Size()
|
||||||
sw = emath.NextPowerOf2Int(sw)
|
sw = emath.NextPowerOf2Int(sw)
|
||||||
sh = emath.NextPowerOf2Int(sh)
|
sh = emath.NextPowerOf2Int(sh)
|
||||||
|
@ -50,15 +50,24 @@ const (
|
|||||||
uniform mat4 projection_matrix;
|
uniform mat4 projection_matrix;
|
||||||
attribute vec2 vertex;
|
attribute vec2 vertex;
|
||||||
attribute vec4 tex_coord;
|
attribute vec4 tex_coord;
|
||||||
|
attribute vec4 color_body0;
|
||||||
|
attribute vec4 color_body1;
|
||||||
|
attribute vec4 color_body2;
|
||||||
|
attribute vec4 color_body3;
|
||||||
|
attribute vec4 color_translate;
|
||||||
varying vec2 varying_tex_coord;
|
varying vec2 varying_tex_coord;
|
||||||
varying vec2 varying_tex_coord_min;
|
varying vec2 varying_tex_coord_min;
|
||||||
varying vec2 varying_tex_coord_max;
|
varying vec2 varying_tex_coord_max;
|
||||||
|
varying mat4 varying_color_body;
|
||||||
|
varying vec4 varying_color_translate;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
varying_tex_coord = vec2(tex_coord[0], tex_coord[1]);
|
varying_tex_coord = vec2(tex_coord[0], tex_coord[1]);
|
||||||
varying_tex_coord_min = vec2(min(tex_coord[0], tex_coord[2]), min(tex_coord[1], tex_coord[3]));
|
varying_tex_coord_min = vec2(min(tex_coord[0], tex_coord[2]), min(tex_coord[1], tex_coord[3]));
|
||||||
varying_tex_coord_max = vec2(max(tex_coord[0], tex_coord[2]), max(tex_coord[1], tex_coord[3]));
|
varying_tex_coord_max = vec2(max(tex_coord[0], tex_coord[2]), max(tex_coord[1], tex_coord[3]));
|
||||||
gl_Position = projection_matrix * vec4(vertex, 0, 1);
|
gl_Position = projection_matrix * vec4(vertex, 0, 1);
|
||||||
|
varying_color_body = mat4(color_body0, color_body1, color_body2, color_body3);
|
||||||
|
varying_color_translate = color_translate;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
shaderStrFragment = `
|
shaderStrFragment = `
|
||||||
@ -73,8 +82,6 @@ precision mediump float;
|
|||||||
{{Definitions}}
|
{{Definitions}}
|
||||||
|
|
||||||
uniform sampler2D texture;
|
uniform sampler2D texture;
|
||||||
uniform mat4 color_matrix_body;
|
|
||||||
uniform vec4 color_matrix_translation;
|
|
||||||
|
|
||||||
uniform highp vec2 source_size;
|
uniform highp vec2 source_size;
|
||||||
|
|
||||||
@ -85,6 +92,8 @@ uniform highp float scale;
|
|||||||
varying highp vec2 varying_tex_coord;
|
varying highp vec2 varying_tex_coord;
|
||||||
varying highp vec2 varying_tex_coord_min;
|
varying highp vec2 varying_tex_coord_min;
|
||||||
varying highp vec2 varying_tex_coord_max;
|
varying highp vec2 varying_tex_coord_max;
|
||||||
|
varying highp mat4 varying_color_body;
|
||||||
|
varying highp vec4 varying_color_translate;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
highp vec2 pos = varying_tex_coord;
|
highp vec2 pos = varying_tex_coord;
|
||||||
@ -148,7 +157,7 @@ void main(void) {
|
|||||||
color.rgb /= color.a;
|
color.rgb /= color.a;
|
||||||
}
|
}
|
||||||
// Apply the color matrix
|
// Apply the color matrix
|
||||||
color = (color_matrix_body * color) + color_matrix_translation;
|
color = (varying_color_body * color) + varying_color_translate;
|
||||||
color = clamp(color, 0.0, 1.0);
|
color = clamp(color, 0.0, 1.0);
|
||||||
// Premultiply alpha
|
// Premultiply alpha
|
||||||
color.rgb *= color.a;
|
color.rgb *= color.a;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package graphicsutil
|
package graphicsutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/affine"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
)
|
)
|
||||||
@ -47,7 +48,7 @@ func isPowerOf2(x int) bool {
|
|||||||
return (x & (x - 1)) == 0
|
return (x & (x - 1)) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32) []float32 {
|
func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32, colorm *affine.ColorM) []float32 {
|
||||||
if !isPowerOf2(width) {
|
if !isPowerOf2(width) {
|
||||||
panic("not reached")
|
panic("not reached")
|
||||||
}
|
}
|
||||||
@ -65,15 +66,16 @@ func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty
|
|||||||
wf := float32(width)
|
wf := float32(width)
|
||||||
hf := float32(height)
|
hf := float32(height)
|
||||||
u0, v0, u1, v1 := float32(sx0)/wf, float32(sy0)/hf, float32(sx1)/wf, float32(sy1)/hf
|
u0, v0, u1, v1 := float32(sx0)/wf, float32(sy0)/hf, float32(sx1)/wf, float32(sy1)/hf
|
||||||
return quadVerticesImpl(float32(sx1-sx0), float32(sy1-sy0), u0, v0, u1, v1, a, b, c, d, tx, ty)
|
return quadVerticesImpl(float32(sx1-sx0), float32(sy1-sy0), u0, v0, u1, v1, a, b, c, d, tx, ty, colorm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func quadVerticesImpl(x, y, u0, v0, u1, v1, a, b, c, d, tx, ty float32) []float32 {
|
func quadVerticesImpl(x, y, u0, v0, u1, v1, a, b, c, d, tx, ty float32, colorm *affine.ColorM) []float32 {
|
||||||
// Specifying a range explicitly here is redundant but this helps optimization
|
// Specifying a range explicitly here is redundant but this helps optimization
|
||||||
// to eliminate boundry checks.
|
// to eliminate boundry checks.
|
||||||
vs := theVerticesBackend.sliceForOneQuad()[0:24]
|
vs := theVerticesBackend.sliceForOneQuad()[0:104]
|
||||||
|
|
||||||
ax, by, cx, dy := a*x, b*y, c*x, d*y
|
ax, by, cx, dy := a*x, b*y, c*x, d*y
|
||||||
|
cbody, ctranslate := colorm.UnsafeElements()
|
||||||
|
|
||||||
// Vertex coordinates
|
// Vertex coordinates
|
||||||
vs[0] = tx
|
vs[0] = tx
|
||||||
@ -88,26 +90,40 @@ func quadVerticesImpl(x, y, u0, v0, u1, v1, a, b, c, d, tx, ty float32) []float3
|
|||||||
vs[5] = v1
|
vs[5] = v1
|
||||||
|
|
||||||
// and the same for the other three coordinates
|
// and the same for the other three coordinates
|
||||||
vs[6] = ax + tx
|
vs[26] = ax + tx
|
||||||
vs[7] = cx + ty
|
vs[27] = cx + ty
|
||||||
vs[8] = u1
|
vs[28] = u1
|
||||||
vs[9] = v0
|
vs[29] = v0
|
||||||
vs[10] = u0
|
vs[30] = u0
|
||||||
vs[11] = v1
|
vs[31] = v1
|
||||||
|
|
||||||
vs[12] = by + tx
|
vs[52] = by + tx
|
||||||
vs[13] = dy + ty
|
vs[53] = dy + ty
|
||||||
vs[14] = u0
|
vs[54] = u0
|
||||||
vs[15] = v1
|
vs[55] = v1
|
||||||
vs[16] = u1
|
vs[56] = u1
|
||||||
vs[17] = v0
|
vs[57] = v0
|
||||||
|
|
||||||
vs[18] = ax + by + tx
|
vs[78] = ax + by + tx
|
||||||
vs[19] = cx + dy + ty
|
vs[79] = cx + dy + ty
|
||||||
vs[20] = u1
|
vs[80] = u1
|
||||||
vs[21] = v1
|
vs[81] = v1
|
||||||
vs[22] = u0
|
vs[82] = u0
|
||||||
vs[23] = v0
|
vs[83] = v0
|
||||||
|
|
||||||
|
// Use for loop since subslicing is heavy on GopherJS.
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
vs[6+i] = cbody[i]
|
||||||
|
vs[32+i] = cbody[i]
|
||||||
|
vs[58+i] = cbody[i]
|
||||||
|
vs[84+i] = cbody[i]
|
||||||
|
}
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
vs[22+i] = ctranslate[i]
|
||||||
|
vs[48+i] = ctranslate[i]
|
||||||
|
vs[74+i] = ctranslate[i]
|
||||||
|
vs[100+i] = ctranslate[i]
|
||||||
|
}
|
||||||
|
|
||||||
return vs
|
return vs
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ type drawImageHistoryItem struct {
|
|||||||
image *Image
|
image *Image
|
||||||
vertices []float32
|
vertices []float32
|
||||||
indices []uint16
|
indices []uint16
|
||||||
colorm *affine.ColorM
|
|
||||||
mode opengl.CompositeMode
|
mode opengl.CompositeMode
|
||||||
filter graphics.Filter
|
filter graphics.Filter
|
||||||
}
|
}
|
||||||
@ -159,9 +158,10 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
|||||||
colorm := (*affine.ColorM)(nil).Scale(0, 0, 0, 0)
|
colorm := (*affine.ColorM)(nil).Scale(0, 0, 0, 0)
|
||||||
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h,
|
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h,
|
||||||
float32(width)/float32(w), 0, 0, float32(height)/float32(h),
|
float32(width)/float32(w), 0, 0, float32(height)/float32(h),
|
||||||
float32(x), float32(y))
|
float32(x), float32(y),
|
||||||
|
colorm)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
i.image.DrawImage(dummyImage.image, vs, is, colorm, opengl.CompositeModeCopy, graphics.FilterNearest)
|
i.image.DrawImage(dummyImage.image, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
}
|
}
|
||||||
|
|
||||||
if x == 0 && y == 0 && width == w && height == h {
|
if x == 0 && y == 0 && width == w && height == h {
|
||||||
@ -198,7 +198,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DrawImage draws a given image img to the image.
|
// DrawImage draws a given image img to the image.
|
||||||
func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode opengl.CompositeMode, filter graphics.Filter) {
|
func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, mode opengl.CompositeMode, filter graphics.Filter) {
|
||||||
if len(vertices) == 0 {
|
if len(vertices) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -207,13 +207,13 @@ func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colo
|
|||||||
if img.stale || img.volatile || i.screen || !IsRestoringEnabled() {
|
if img.stale || img.volatile || i.screen || !IsRestoringEnabled() {
|
||||||
i.makeStale()
|
i.makeStale()
|
||||||
} else {
|
} else {
|
||||||
i.appendDrawImageHistory(img, vertices, indices, colorm, mode, filter)
|
i.appendDrawImageHistory(img, vertices, indices, mode, filter)
|
||||||
}
|
}
|
||||||
i.image.DrawImage(img.image, vertices, indices, colorm, mode, filter)
|
i.image.DrawImage(img.image, vertices, indices, mode, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendDrawImageHistory appends a draw-image history item to the image.
|
// appendDrawImageHistory appends a draw-image history item to the image.
|
||||||
func (i *Image) appendDrawImageHistory(image *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode opengl.CompositeMode, filter graphics.Filter) {
|
func (i *Image) appendDrawImageHistory(image *Image, vertices []float32, indices []uint16, mode opengl.CompositeMode, filter graphics.Filter) {
|
||||||
if i.stale || i.volatile || i.screen {
|
if i.stale || i.volatile || i.screen {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -228,7 +228,6 @@ func (i *Image) appendDrawImageHistory(image *Image, vertices []float32, indices
|
|||||||
image: image,
|
image: image,
|
||||||
vertices: vertices,
|
vertices: vertices,
|
||||||
indices: indices,
|
indices: indices,
|
||||||
colorm: colorm,
|
|
||||||
mode: mode,
|
mode: mode,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
}
|
}
|
||||||
@ -359,7 +358,7 @@ func (i *Image) restore() error {
|
|||||||
if c.image.hasDependency() {
|
if c.image.hasDependency() {
|
||||||
panic("not reached")
|
panic("not reached")
|
||||||
}
|
}
|
||||||
gimg.DrawImage(c.image.image, c.vertices, c.indices, c.colorm, c.mode, c.filter)
|
gimg.DrawImage(c.image.image, c.vertices, c.indices, c.mode, c.filter)
|
||||||
}
|
}
|
||||||
i.image = gimg
|
i.image = gimg
|
||||||
|
|
||||||
|
@ -116,9 +116,9 @@ func TestRestoreChain(t *testing.T) {
|
|||||||
fill(imgs[0], clr.R, clr.G, clr.B, clr.A)
|
fill(imgs[0], clr.R, clr.G, clr.B, clr.A)
|
||||||
for i := 0; i < num-1; i++ {
|
for i := 0; i < num-1; i++ {
|
||||||
w, h := imgs[i].Size()
|
w, h := imgs[i].Size()
|
||||||
vs := graphicsutil.QuadVertices(w, h, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(w, h, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
imgs[i+1].DrawImage(imgs[i], vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
imgs[i+1].DrawImage(imgs[i], vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
}
|
}
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
if err := Restore(); err != nil {
|
if err := Restore(); err != nil {
|
||||||
@ -158,12 +158,12 @@ func TestRestoreChain2(t *testing.T) {
|
|||||||
clr8 := color.RGBA{0x00, 0x00, 0xff, 0xff}
|
clr8 := color.RGBA{0x00, 0x00, 0xff, 0xff}
|
||||||
fill(imgs[8], clr8.R, clr8.G, clr8.B, clr8.A)
|
fill(imgs[8], clr8.R, clr8.G, clr8.B, clr8.A)
|
||||||
|
|
||||||
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
imgs[8].DrawImage(imgs[7], vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
imgs[8].DrawImage(imgs[7], vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
imgs[9].DrawImage(imgs[8], vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
imgs[9].DrawImage(imgs[8], vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
imgs[i+1].DrawImage(imgs[i], vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
imgs[i+1].DrawImage(imgs[i], vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
@ -204,12 +204,12 @@ func TestRestoreOverrideSource(t *testing.T) {
|
|||||||
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
|
clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff}
|
||||||
clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff}
|
clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff}
|
||||||
fill(img1, clr0.R, clr0.G, clr0.B, clr0.A)
|
fill(img1, clr0.R, clr0.G, clr0.B, clr0.A)
|
||||||
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
img2.DrawImage(img1, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img2.DrawImage(img1, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
img3.DrawImage(img2, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img3.DrawImage(img2, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
fill(img0, clr1.R, clr1.G, clr1.B, clr1.A)
|
fill(img0, clr1.R, clr1.G, clr1.B, clr1.A)
|
||||||
img1.DrawImage(img0, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img1.DrawImage(img0, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
if err := Restore(); err != nil {
|
if err := Restore(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -289,25 +289,25 @@ func TestRestoreComplexGraph(t *testing.T) {
|
|||||||
img1.Dispose()
|
img1.Dispose()
|
||||||
img0.Dispose()
|
img0.Dispose()
|
||||||
}()
|
}()
|
||||||
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
img3.DrawImage(img0, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img3.DrawImage(img0, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 1, 0)
|
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 1, 0, nil)
|
||||||
img3.DrawImage(img1, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img3.DrawImage(img1, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 1, 0)
|
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 1, 0, nil)
|
||||||
img4.DrawImage(img1, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img4.DrawImage(img1, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 2, 0)
|
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 2, 0, nil)
|
||||||
img4.DrawImage(img2, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img4.DrawImage(img2, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0)
|
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0, nil)
|
||||||
img5.DrawImage(img3, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img5.DrawImage(img3, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0)
|
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0, nil)
|
||||||
img6.DrawImage(img3, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img6.DrawImage(img3, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 1, 0)
|
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 1, 0, nil)
|
||||||
img6.DrawImage(img4, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img6.DrawImage(img4, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0)
|
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0, nil)
|
||||||
img7.DrawImage(img2, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img7.DrawImage(img2, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 2, 0)
|
vs = graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 2, 0, nil)
|
||||||
img7.DrawImage(img3, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img7.DrawImage(img3, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
if err := Restore(); err != nil {
|
if err := Restore(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -397,10 +397,10 @@ func TestRestoreRecursive(t *testing.T) {
|
|||||||
img1.Dispose()
|
img1.Dispose()
|
||||||
img0.Dispose()
|
img0.Dispose()
|
||||||
}()
|
}()
|
||||||
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 1, 0)
|
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 1, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
img1.DrawImage(img0, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img1.DrawImage(img0, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
img0.DrawImage(img1, vs, is, nil, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
img0.DrawImage(img1, vs, is, opengl.CompositeModeSourceOver, graphics.FilterNearest)
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
if err := Restore(); err != nil {
|
if err := Restore(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -485,9 +485,9 @@ func TestDrawImageAndReplacePixels(t *testing.T) {
|
|||||||
img1 := NewImage(2, 1, false)
|
img1 := NewImage(2, 1, false)
|
||||||
defer img1.Dispose()
|
defer img1.Dispose()
|
||||||
|
|
||||||
vs := graphicsutil.QuadVertices(1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
img1.DrawImage(img0, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img1.DrawImage(img0, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff}, 1, 0, 1, 1)
|
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff}, 1, 0, 1, 1)
|
||||||
|
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
@ -517,10 +517,10 @@ func TestDispose(t *testing.T) {
|
|||||||
img2 := newImageFromImage(base2)
|
img2 := newImageFromImage(base2)
|
||||||
defer img2.Dispose()
|
defer img2.Dispose()
|
||||||
|
|
||||||
vs := graphicsutil.QuadVertices(1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
img1.DrawImage(img2, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img1.DrawImage(img2, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
img0.DrawImage(img1, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img0.DrawImage(img1, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
img1.Dispose()
|
img1.Dispose()
|
||||||
|
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
@ -545,9 +545,9 @@ func TestDoubleResolve(t *testing.T) {
|
|||||||
base.Pix[3] = 0xff
|
base.Pix[3] = 0xff
|
||||||
img1 := newImageFromImage(base)
|
img1 := newImageFromImage(base)
|
||||||
|
|
||||||
vs := graphicsutil.QuadVertices(1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
img0.DrawImage(img1, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img0.DrawImage(img1, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
img0.ReplacePixels([]uint8{0x00, 0xff, 0x00, 0xff}, 1, 1, 1, 1)
|
img0.ReplacePixels([]uint8{0x00, 0xff, 0x00, 0xff}, 1, 1, 1, 1)
|
||||||
// Now img0 is stale.
|
// Now img0 is stale.
|
||||||
ResolveStaleImages()
|
ResolveStaleImages()
|
||||||
|
@ -63,9 +63,9 @@ func (b *backend) TryAlloc(width, height int) (*packing.Node, bool) {
|
|||||||
newImg := restorable.NewImage(s, s, false)
|
newImg := restorable.NewImage(s, s, false)
|
||||||
oldImg := b.restorable
|
oldImg := b.restorable
|
||||||
w, h := oldImg.Size()
|
w, h := oldImg.Size()
|
||||||
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(w, h, 0, 0, w, h, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
newImg.DrawImage(oldImg, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
newImg.DrawImage(oldImg, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
oldImg.Dispose()
|
oldImg.Dispose()
|
||||||
b.restorable = newImg
|
b.restorable = newImg
|
||||||
|
|
||||||
@ -129,9 +129,9 @@ func (i *Image) ensureNotShared() {
|
|||||||
x, y, w, h := i.region()
|
x, y, w, h := i.region()
|
||||||
newImg := restorable.NewImage(w, h, false)
|
newImg := restorable.NewImage(w, h, false)
|
||||||
vw, vh := i.backend.restorable.Size()
|
vw, vh := i.backend.restorable.Size()
|
||||||
vs := graphicsutil.QuadVertices(vw, vh, x, y, x+w, y+h, 1, 0, 0, 1, 0, 0)
|
vs := graphicsutil.QuadVertices(vw, vh, x, y, x+w, y+h, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
newImg.DrawImage(i.backend.restorable, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
newImg.DrawImage(i.backend.restorable, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
|
|
||||||
i.dispose(false)
|
i.dispose(false)
|
||||||
i.backend = &backend{
|
i.backend = &backend{
|
||||||
@ -184,18 +184,18 @@ func (i *Image) Size() (width, height int) {
|
|||||||
return i.width, i.height
|
return i.width, i.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) QuadVertices(sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32) []float32 {
|
func (i *Image) QuadVertices(sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32, colorm *affine.ColorM) []float32 {
|
||||||
if i.backend == nil {
|
if i.backend == nil {
|
||||||
i.allocate(true)
|
i.allocate(true)
|
||||||
}
|
}
|
||||||
dx, dy, _, _ := i.region()
|
dx, dy, _, _ := i.region()
|
||||||
w, h := i.backend.restorable.SizePowerOf2()
|
w, h := i.backend.restorable.SizePowerOf2()
|
||||||
return graphicsutil.QuadVertices(w, h, sx0+dx, sy0+dy, sx1+dx, sy1+dy, a, b, c, d, tx, ty)
|
return graphicsutil.QuadVertices(w, h, sx0+dx, sy0+dy, sx1+dx, sy1+dy, a, b, c, d, tx, ty, colorm)
|
||||||
}
|
}
|
||||||
|
|
||||||
const MaxCountForShare = 10
|
const MaxCountForShare = 10
|
||||||
|
|
||||||
func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode opengl.CompositeMode, filter graphics.Filter) {
|
func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, mode opengl.CompositeMode, filter graphics.Filter) {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
defer backendsM.Unlock()
|
defer backendsM.Unlock()
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colo
|
|||||||
panic("shareable: Image.DrawImage: img must be different from the receiver")
|
panic("shareable: Image.DrawImage: img must be different from the receiver")
|
||||||
}
|
}
|
||||||
|
|
||||||
i.backend.restorable.DrawImage(img.backend.restorable, vertices, indices, colorm, mode, filter)
|
i.backend.restorable.DrawImage(img.backend.restorable, vertices, indices, mode, filter)
|
||||||
|
|
||||||
i.countForShare = 0
|
i.countForShare = 0
|
||||||
if !img.isShared() && img.shareable() {
|
if !img.isShared() && img.shareable() {
|
||||||
|
@ -86,9 +86,9 @@ func TestEnsureNotShared(t *testing.T) {
|
|||||||
dy1 = size * 3 / 4
|
dy1 = size * 3 / 4
|
||||||
)
|
)
|
||||||
// img4.ensureNotShared() should be called.
|
// img4.ensureNotShared() should be called.
|
||||||
vs := img3.QuadVertices(0, 0, size/2, size/2, 1, 0, 0, 1, size/4, size/4)
|
vs := img3.QuadVertices(0, 0, size/2, size/2, 1, 0, 0, 1, size/4, size/4, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
img4.DrawImage(img3, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img4.DrawImage(img3, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
want := false
|
want := false
|
||||||
if got := img4.IsSharedForTesting(); got != want {
|
if got := img4.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -110,7 +110,7 @@ func TestEnsureNotShared(t *testing.T) {
|
|||||||
|
|
||||||
// Check further drawing doesn't cause panic.
|
// Check further drawing doesn't cause panic.
|
||||||
// This bug was fixed by 03dcd948.
|
// This bug was fixed by 03dcd948.
|
||||||
img4.DrawImage(img3, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img4.DrawImage(img3, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReshared(t *testing.T) {
|
func TestReshared(t *testing.T) {
|
||||||
@ -150,9 +150,9 @@ func TestReshared(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use img1 as a render target.
|
// Use img1 as a render target.
|
||||||
vs := img2.QuadVertices(0, 0, size, size, 1, 0, 0, 1, 0, 0)
|
vs := img2.QuadVertices(0, 0, size, size, 1, 0, 0, 1, 0, 0, nil)
|
||||||
is := graphicsutil.QuadIndices()
|
is := graphicsutil.QuadIndices()
|
||||||
img1.DrawImage(img2, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img1.DrawImage(img2, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
want = false
|
want = false
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
if got := img1.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -160,7 +160,7 @@ func TestReshared(t *testing.T) {
|
|||||||
|
|
||||||
// Use img1 as a render source.
|
// Use img1 as a render source.
|
||||||
for i := 0; i < MaxCountForShare-1; i++ {
|
for i := 0; i < MaxCountForShare-1; i++ {
|
||||||
img0.DrawImage(img1, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img0.DrawImage(img1, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
want := false
|
want := false
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
if got := img1.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -177,7 +177,7 @@ func TestReshared(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img0.DrawImage(img1, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img0.DrawImage(img1, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
want = true
|
want = true
|
||||||
if got := img1.IsSharedForTesting(); got != want {
|
if got := img1.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
@ -195,7 +195,7 @@ func TestReshared(t *testing.T) {
|
|||||||
|
|
||||||
// Use img3 as a render source. img3 never uses a shared texture.
|
// Use img3 as a render source. img3 never uses a shared texture.
|
||||||
for i := 0; i < MaxCountForShare*2; i++ {
|
for i := 0; i < MaxCountForShare*2; i++ {
|
||||||
img0.DrawImage(img3, vs, is, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
img0.DrawImage(img3, vs, is, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||||
want := false
|
want := false
|
||||||
if got := img3.IsSharedForTesting(); got != want {
|
if got := img3.IsSharedForTesting(); got != want {
|
||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
|
Loading…
Reference in New Issue
Block a user