Compare commits

...

7 Commits

Author SHA1 Message Date
Hajime Hoshi
b6ab7a10c1 internal/graphics: unify QuadVertices
This is a preparation for adding members to Vertex.

Updates #2640
2024-08-12 00:29:24 +09:00
Hajime Hoshi
6cd00f3b88 internal/graphicsdriver/opengl: exclude playstation5 2024-08-11 22:41:21 +09:00
Hajime Hoshi
9a751d7c26 internal/mipmap: refactoring 2024-08-11 22:33:21 +09:00
Hajime Hoshi
e6807794f2 internal/mipmap: refactoring 2024-08-11 22:29:15 +09:00
Hajime Hoshi
5e820be911 internal/buffered: refactoring
This is a preparation for adding members to Vertex.

Updates #2640
2024-08-11 22:25:45 +09:00
Hajime Hoshi
5f80f4b3de all: refactoring 2024-08-11 21:43:00 +09:00
Hajime Hoshi
b9c24f786a ebiten: add BenchmarkDrawTriangles 2024-08-11 16:41:19 +09:00
13 changed files with 217 additions and 127 deletions

View File

@ -247,7 +247,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) {
colorm, cr, cg, cb, ca := colorMToScale(options.ColorM.affineColorM()) colorm, cr, cg, cb, ca := colorMToScale(options.ColorM.affineColorM())
cr, cg, cb, ca = options.ColorScale.apply(cr, cg, cb, ca) cr, cg, cb, ca = options.ColorScale.apply(cr, cg, cb, ca)
vs := i.ensureTmpVertices(4 * graphics.VertexFloatCount) vs := i.ensureTmpVertices(4 * graphics.VertexFloatCount)
graphics.QuadVertices(vs, float32(sx0), float32(sy0), float32(sx1), float32(sy1), a, b, c, d, tx, ty, cr, cg, cb, ca) graphics.QuadVerticesFromSrcAndMatrix(vs, float32(sx0), float32(sy0), float32(sx1), float32(sy1), a, b, c, d, tx, ty, cr, cg, cb, ca)
is := graphics.QuadIndices() is := graphics.QuadIndices()
srcs := [graphics.ShaderSrcImageCount]*ui.Image{img.image} srcs := [graphics.ShaderSrcImageCount]*ui.Image{img.image}
@ -829,7 +829,7 @@ func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawR
vs := i.ensureTmpVertices(4 * graphics.VertexFloatCount) vs := i.ensureTmpVertices(4 * graphics.VertexFloatCount)
// Do not use srcRegions[0].Dx() and srcRegions[0].Dy() as these might be empty. // Do not use srcRegions[0].Dx() and srcRegions[0].Dy() as these might be empty.
graphics.QuadVertices(vs, graphics.QuadVerticesFromSrcAndMatrix(vs,
float32(srcRegions[0].Min.X), float32(srcRegions[0].Min.Y), float32(srcRegions[0].Min.X), float32(srcRegions[0].Min.Y),
float32(srcRegions[0].Min.X+width), float32(srcRegions[0].Min.Y+height), float32(srcRegions[0].Min.X+width), float32(srcRegions[0].Min.Y+height),
a, b, c, d, tx, ty, cr, cg, cb, ca) a, b, c, d, tx, ty, cr, cg, cb, ca)

View File

@ -662,6 +662,59 @@ func BenchmarkDrawImage(b *testing.B) {
} }
} }
func BenchmarkDrawTriangles(b *testing.B) {
const w, h = 16, 16
img0 := ebiten.NewImage(w, h)
img1 := ebiten.NewImage(w, h)
op := &ebiten.DrawTrianglesOptions{}
vs := []ebiten.Vertex{
{
DstX: 0,
DstY: 0,
SrcX: 0,
SrcY: 0,
ColorR: 1,
ColorG: 1,
ColorB: 1,
ColorA: 1,
},
{
DstX: w,
DstY: 0,
SrcX: w,
SrcY: 0,
ColorR: 1,
ColorG: 1,
ColorB: 1,
ColorA: 1,
},
{
DstX: 0,
DstY: h,
SrcX: 0,
SrcY: h,
ColorR: 1,
ColorG: 1,
ColorB: 1,
ColorA: 1,
},
{
DstX: w,
DstY: h,
SrcX: w,
SrcY: h,
ColorR: 1,
ColorG: 1,
ColorB: 1,
ColorA: 1,
},
}
is := []uint16{0, 1, 2, 1, 2, 3}
for i := 0; i < b.N; i++ {
img0.DrawTriangles(vs, is, img1, op)
}
}
func TestImageLinearGraduation(t *testing.T) { func TestImageLinearGraduation(t *testing.T) {
img0 := ebiten.NewImage(2, 2) img0 := ebiten.NewImage(2, 2)
img0.WritePixels([]byte{ img0.WritePixels([]byte{

View File

@ -43,16 +43,6 @@ func min(a, b int) int {
return b return b
} }
// quadVertices returns vertices to render a quad. These values are passed to graphicscommand.Image.
func quadVertices(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1, cr, cg, cb, ca float32) []float32 {
return []float32{
dx0, dy0, sx0, sy0, cr, cg, cb, ca,
dx1, dy0, sx1, sy0, cr, cg, cb, ca,
dx0, dy1, sx0, sy1, cr, cg, cb, ca,
dx1, dy1, sx1, sy1, cr, cg, cb, ca,
}
}
func appendDeferred(f func()) { func appendDeferred(f func()) {
deferredM.Lock() deferredM.Lock()
defer deferredM.Unlock() defer deferredM.Unlock()
@ -149,7 +139,8 @@ func (b *backend) extendIfNeeded(width, height int) {
srcs := [graphics.ShaderSrcImageCount]*graphicscommand.Image{b.image} srcs := [graphics.ShaderSrcImageCount]*graphicscommand.Image{b.image}
sw, sh := b.image.InternalSize() sw, sh := b.image.InternalSize()
vs := quadVertices(0, 0, float32(sw), float32(sh), 0, 0, float32(sw), float32(sh), 1, 1, 1, 1) vs := make([]float32, 4*graphics.VertexFloatCount)
graphics.QuadVerticesFromDstAndSrc(vs, 0, 0, float32(sw), float32(sh), 0, 0, float32(sw), float32(sh), 1, 1, 1, 1)
is := graphics.QuadIndices() is := graphics.QuadIndices()
dr := image.Rect(0, 0, sw, sh) dr := image.Rect(0, 0, sw, sh)
newImg.DrawTriangles(srcs, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, NearestFilterShader.ensureShader(), nil, graphicsdriver.FillRuleFillAll) newImg.DrawTriangles(srcs, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, NearestFilterShader.ensureShader(), nil, graphicsdriver.FillRuleFillAll)
@ -174,7 +165,8 @@ func newClearedImage(width, height int, screen bool) *graphicscommand.Image {
} }
func clearImage(i *graphicscommand.Image, region image.Rectangle) { func clearImage(i *graphicscommand.Image, region image.Rectangle) {
vs := quadVertices(float32(region.Min.X), float32(region.Min.Y), float32(region.Max.X), float32(region.Max.Y), 0, 0, 0, 0, 0, 0, 0, 0) vs := make([]float32, 4*graphics.VertexFloatCount)
graphics.QuadVerticesFromDstAndSrc(vs, float32(region.Min.X), float32(region.Min.Y), float32(region.Max.X), float32(region.Max.Y), 0, 0, 0, 0, 0, 0, 0, 0)
is := graphics.QuadIndices() is := graphics.QuadIndices()
i.DrawTriangles([graphics.ShaderSrcImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendClear, region, [graphics.ShaderSrcImageCount]image.Rectangle{}, clearShader.ensureShader(), nil, graphicsdriver.FillRuleFillAll) i.DrawTriangles([graphics.ShaderSrcImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendClear, region, [graphics.ShaderSrcImageCount]image.Rectangle{}, clearShader.ensureShader(), nil, graphicsdriver.FillRuleFillAll)
} }
@ -353,7 +345,7 @@ func (i *Image) ensureIsolatedFromSource(backends []*backend) {
w, h := float32(i.width), float32(i.height) w, h := float32(i.width), float32(i.height)
vs := make([]float32, 4*graphics.VertexFloatCount) vs := make([]float32, 4*graphics.VertexFloatCount)
graphics.QuadVertices(vs, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1) graphics.QuadVerticesFromSrcAndMatrix(vs, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices() is := graphics.QuadIndices()
dr := image.Rect(0, 0, i.width, i.height) dr := image.Rect(0, 0, i.width, i.height)
@ -384,7 +376,7 @@ func (i *Image) putOnSourceBackend() {
w, h := float32(i.width), float32(i.height) w, h := float32(i.width), float32(i.height)
vs := make([]float32, 4*graphics.VertexFloatCount) vs := make([]float32, 4*graphics.VertexFloatCount)
graphics.QuadVertices(vs, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1) graphics.QuadVerticesFromSrcAndMatrix(vs, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices() is := graphics.QuadIndices()
dr := image.Rect(0, 0, i.width, i.height) dr := image.Rect(0, 0, i.width, i.height)
newI.drawTriangles([graphics.ShaderSrcImageCount]*Image{i}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, NearestFilterShader, nil, graphicsdriver.FillRuleFillAll) newI.drawTriangles([graphics.ShaderSrcImageCount]*Image{i}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, NearestFilterShader, nil, graphicsdriver.FillRuleFillAll)

View File

@ -50,12 +50,9 @@ func quadVertices(sw, sh, x, y int, scalex float32) []float32 {
sy0 := float32(0) sy0 := float32(0)
sx1 := float32(sw) sx1 := float32(sw)
sy1 := float32(sh) sy1 := float32(sh)
return []float32{ vs := make([]float32, 4*graphics.VertexFloatCount)
dx0, dy0, sx0, sy0, 1, 1, 1, 1, graphics.QuadVerticesFromDstAndSrc(vs, dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1, 1, 1, 1, 1)
dx1, dy0, sx1, sy0, 1, 1, 1, 1, return vs
dx0, dy1, sx0, sy1, 1, 1, 1, 1,
dx1, dy1, sx1, sy1, 1, 1, 1, 1,
}
} }
const bigSize = 2049 const bigSize = 2049

View File

@ -246,45 +246,51 @@ func (i *Image) syncPixelsIfNeeded() {
cbf := float32(c[2]) / 0xff cbf := float32(c[2]) / 0xff
caf := float32(c[3]) / 0xff caf := float32(c[3]) / 0xff
vs[graphics.VertexFloatCount*4*idx] = dx vidx := 4 * idx
vs[graphics.VertexFloatCount*4*idx+1] = dy iidx := 6 * idx
vs[graphics.VertexFloatCount*4*idx+2] = sx
vs[graphics.VertexFloatCount*4*idx+3] = sy
vs[graphics.VertexFloatCount*4*idx+4] = crf
vs[graphics.VertexFloatCount*4*idx+5] = cgf
vs[graphics.VertexFloatCount*4*idx+6] = cbf
vs[graphics.VertexFloatCount*4*idx+7] = caf
vs[graphics.VertexFloatCount*4*idx+8] = dx + 1
vs[graphics.VertexFloatCount*4*idx+9] = dy
vs[graphics.VertexFloatCount*4*idx+10] = sx + 1
vs[graphics.VertexFloatCount*4*idx+11] = sy
vs[graphics.VertexFloatCount*4*idx+12] = crf
vs[graphics.VertexFloatCount*4*idx+13] = cgf
vs[graphics.VertexFloatCount*4*idx+14] = cbf
vs[graphics.VertexFloatCount*4*idx+15] = caf
vs[graphics.VertexFloatCount*4*idx+16] = dx
vs[graphics.VertexFloatCount*4*idx+17] = dy + 1
vs[graphics.VertexFloatCount*4*idx+18] = sx
vs[graphics.VertexFloatCount*4*idx+19] = sy + 1
vs[graphics.VertexFloatCount*4*idx+20] = crf
vs[graphics.VertexFloatCount*4*idx+21] = cgf
vs[graphics.VertexFloatCount*4*idx+22] = cbf
vs[graphics.VertexFloatCount*4*idx+23] = caf
vs[graphics.VertexFloatCount*4*idx+24] = dx + 1
vs[graphics.VertexFloatCount*4*idx+25] = dy + 1
vs[graphics.VertexFloatCount*4*idx+26] = sx + 1
vs[graphics.VertexFloatCount*4*idx+27] = sy + 1
vs[graphics.VertexFloatCount*4*idx+28] = crf
vs[graphics.VertexFloatCount*4*idx+29] = cgf
vs[graphics.VertexFloatCount*4*idx+30] = cbf
vs[graphics.VertexFloatCount*4*idx+31] = caf
is[6*idx] = uint32(4 * idx) vs[graphics.VertexFloatCount*vidx] = dx
is[6*idx+1] = uint32(4*idx + 1) vs[graphics.VertexFloatCount*vidx+1] = dy
is[6*idx+2] = uint32(4*idx + 2) vs[graphics.VertexFloatCount*vidx+2] = sx
is[6*idx+3] = uint32(4*idx + 1) vs[graphics.VertexFloatCount*vidx+3] = sy
is[6*idx+4] = uint32(4*idx + 2) vs[graphics.VertexFloatCount*vidx+4] = crf
is[6*idx+5] = uint32(4*idx + 3) vs[graphics.VertexFloatCount*vidx+5] = cgf
vs[graphics.VertexFloatCount*vidx+6] = cbf
vs[graphics.VertexFloatCount*vidx+7] = caf
vs[graphics.VertexFloatCount*(vidx+1)] = dx + 1
vs[graphics.VertexFloatCount*(vidx+1)+1] = dy
vs[graphics.VertexFloatCount*(vidx+1)+2] = sx + 1
vs[graphics.VertexFloatCount*(vidx+1)+3] = sy
vs[graphics.VertexFloatCount*(vidx+1)+4] = crf
vs[graphics.VertexFloatCount*(vidx+1)+5] = cgf
vs[graphics.VertexFloatCount*(vidx+1)+6] = cbf
vs[graphics.VertexFloatCount*(vidx+1)+7] = caf
vs[graphics.VertexFloatCount*(vidx+2)] = dx
vs[graphics.VertexFloatCount*(vidx+2)+1] = dy + 1
vs[graphics.VertexFloatCount*(vidx+2)+2] = sx
vs[graphics.VertexFloatCount*(vidx+2)+3] = sy + 1
vs[graphics.VertexFloatCount*(vidx+2)+4] = crf
vs[graphics.VertexFloatCount*(vidx+2)+5] = cgf
vs[graphics.VertexFloatCount*(vidx+2)+6] = cbf
vs[graphics.VertexFloatCount*(vidx+2)+7] = caf
vs[graphics.VertexFloatCount*(vidx+3)] = dx + 1
vs[graphics.VertexFloatCount*(vidx+3)+1] = dy + 1
vs[graphics.VertexFloatCount*(vidx+3)+2] = sx + 1
vs[graphics.VertexFloatCount*(vidx+3)+3] = sy + 1
vs[graphics.VertexFloatCount*(vidx+3)+4] = crf
vs[graphics.VertexFloatCount*(vidx+3)+5] = cgf
vs[graphics.VertexFloatCount*(vidx+3)+6] = cbf
vs[graphics.VertexFloatCount*(vidx+3)+7] = caf
is[iidx] = uint32(vidx)
is[iidx+1] = uint32(vidx + 1)
is[iidx+2] = uint32(vidx + 2)
is[iidx+3] = uint32(vidx + 1)
is[iidx+4] = uint32(vidx + 2)
is[iidx+5] = uint32(vidx + 3)
idx++ idx++
} }

View File

@ -52,7 +52,7 @@ func TestUnsyncedPixels(t *testing.T) {
// Flush unsynced pixel cache. // Flush unsynced pixel cache.
src := buffered.NewImage(16, 16, atlas.ImageTypeRegular) src := buffered.NewImage(16, 16, atlas.ImageTypeRegular)
vs := make([]float32, 4*graphics.VertexFloatCount) vs := make([]float32, 4*graphics.VertexFloatCount)
graphics.QuadVertices(vs, 0, 0, 16, 16, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1) graphics.QuadVerticesFromSrcAndMatrix(vs, 0, 0, 16, 16, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices() is := graphics.QuadIndices()
dr := image.Rect(0, 0, 16, 16) dr := image.Rect(0, 0, 16, 16)
sr := [graphics.ShaderSrcImageCount]image.Rectangle{image.Rect(0, 0, 16, 16)} sr := [graphics.ShaderSrcImageCount]image.Rectangle{image.Rect(0, 0, 16, 16)}

View File

@ -50,16 +50,16 @@ func QuadIndices() []uint32 {
return quadIndices return quadIndices
} }
// QuadVertices sets a float32 slice for a quadrangle. // QuadVerticesFromSrcAndMatrix sets a float32 slice for a quadrangle.
// QuadVertices sets a slice that never overlaps with other slices returned this function, func QuadVerticesFromSrcAndMatrix(dst []float32, sx0, sy0, sx1, sy1 float32, a, b, c, d, tx, ty float32, cr, cg, cb, ca float32) {
// and users can do optimization based on this fact.
func QuadVertices(dst []float32, sx0, sy0, sx1, sy1 float32, a, b, c, d, tx, ty float32, cr, cg, cb, ca float32) {
x := sx1 - sx0 x := sx1 - sx0
y := sy1 - sy0 y := sy1 - sy0
ax, by, cx, dy := a*x, b*y, c*x, d*y ax, by, cx, dy := a*x, b*y, c*x, d*y
u0, v0, u1, v1 := sx0, sy0, sx1, sy1 u0, v0, u1, v1 := sx0, sy0, sx1, sy1
// This function is very performance-sensitive and implement in a very dumb way. // This function is very performance-sensitive and implement in a very dumb way.
// Remove the boundary check.
dst = dst[:4*VertexFloatCount] dst = dst[:4*VertexFloatCount]
dst[0] = adjustDestinationPixel(tx) dst[0] = adjustDestinationPixel(tx)
@ -71,32 +71,79 @@ func QuadVertices(dst []float32, sx0, sy0, sx1, sy1 float32, a, b, c, d, tx, ty
dst[6] = cb dst[6] = cb
dst[7] = ca dst[7] = ca
dst[8] = adjustDestinationPixel(ax + tx) dst[VertexFloatCount] = adjustDestinationPixel(ax + tx)
dst[9] = adjustDestinationPixel(cx + ty) dst[VertexFloatCount+1] = adjustDestinationPixel(cx + ty)
dst[10] = u1 dst[VertexFloatCount+2] = u1
dst[11] = v0 dst[VertexFloatCount+3] = v0
dst[12] = cr dst[VertexFloatCount+4] = cr
dst[13] = cg dst[VertexFloatCount+5] = cg
dst[14] = cb dst[VertexFloatCount+6] = cb
dst[15] = ca dst[VertexFloatCount+7] = ca
dst[16] = adjustDestinationPixel(by + tx) dst[2*VertexFloatCount] = adjustDestinationPixel(by + tx)
dst[17] = adjustDestinationPixel(dy + ty) dst[2*VertexFloatCount+1] = adjustDestinationPixel(dy + ty)
dst[18] = u0 dst[2*VertexFloatCount+2] = u0
dst[19] = v1 dst[2*VertexFloatCount+3] = v1
dst[20] = cr dst[2*VertexFloatCount+4] = cr
dst[21] = cg dst[2*VertexFloatCount+5] = cg
dst[22] = cb dst[2*VertexFloatCount+6] = cb
dst[23] = ca dst[2*VertexFloatCount+7] = ca
dst[24] = adjustDestinationPixel(ax + by + tx) dst[3*VertexFloatCount] = adjustDestinationPixel(ax + by + tx)
dst[25] = adjustDestinationPixel(cx + dy + ty) dst[3*VertexFloatCount+1] = adjustDestinationPixel(cx + dy + ty)
dst[26] = u1 dst[3*VertexFloatCount+2] = u1
dst[27] = v1 dst[3*VertexFloatCount+3] = v1
dst[28] = cr dst[3*VertexFloatCount+4] = cr
dst[29] = cg dst[3*VertexFloatCount+5] = cg
dst[30] = cb dst[3*VertexFloatCount+6] = cb
dst[31] = ca dst[3*VertexFloatCount+7] = ca
}
// QuadVerticesFromDstAndSrc sets a float32 slice for a quadrangle.
func QuadVerticesFromDstAndSrc(dst []float32, dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1, cr, cg, cb, ca float32) {
dx0 = adjustDestinationPixel(dx0)
dy0 = adjustDestinationPixel(dy0)
dx1 = adjustDestinationPixel(dx1)
dy1 = adjustDestinationPixel(dy1)
// Remove the boundary check.
dst = dst[:4*VertexFloatCount]
dst[0] = dx0
dst[1] = dy0
dst[2] = sx0
dst[3] = sy0
dst[4] = cr
dst[5] = cg
dst[6] = cb
dst[7] = ca
dst[VertexFloatCount] = dx1
dst[VertexFloatCount+1] = dy0
dst[VertexFloatCount+2] = sx1
dst[VertexFloatCount+3] = sy0
dst[VertexFloatCount+4] = cr
dst[VertexFloatCount+5] = cg
dst[VertexFloatCount+6] = cb
dst[VertexFloatCount+7] = ca
dst[2*VertexFloatCount] = dx0
dst[2*VertexFloatCount+1] = dy1
dst[2*VertexFloatCount+2] = sx0
dst[2*VertexFloatCount+3] = sy1
dst[2*VertexFloatCount+4] = cr
dst[2*VertexFloatCount+5] = cg
dst[2*VertexFloatCount+6] = cb
dst[2*VertexFloatCount+7] = ca
dst[3*VertexFloatCount] = dx1
dst[3*VertexFloatCount+1] = dy1
dst[3*VertexFloatCount+2] = sx1
dst[3*VertexFloatCount+3] = sy1
dst[3*VertexFloatCount+4] = cr
dst[3*VertexFloatCount+5] = cg
dst[3*VertexFloatCount+6] = cb
dst[3*VertexFloatCount+7] = ca
} }
func adjustDestinationPixel(x float32) float32 { func adjustDestinationPixel(x float32) float32 {

View File

@ -183,9 +183,9 @@ func dstRegionFromVertices(vertices []float32) (minX, minY, maxX, maxY float32)
maxX = negInf32 maxX = negInf32
maxY = negInf32 maxY = negInf32
for i := 0; i < len(vertices)/graphics.VertexFloatCount; i++ { for i := 0; i < len(vertices); i += graphics.VertexFloatCount {
x := vertices[graphics.VertexFloatCount*i] x := vertices[i]
y := vertices[graphics.VertexFloatCount*i+1] y := vertices[i+1]
if x < minX { if x < minX {
minX = x minX = x
} }

View File

@ -43,12 +43,9 @@ func TestMain(m *testing.M) {
} }
func quadVertices(w, h float32) []float32 { func quadVertices(w, h float32) []float32 {
return []float32{ vs := make([]float32, 8*graphics.VertexFloatCount)
0, 0, 0, 0, 1, 1, 1, 1, graphics.QuadVerticesFromDstAndSrc(vs, 0, 0, w, h, 0, 0, w, h, 1, 1, 1, 1)
w, 0, w, 0, 1, 1, 1, 1, return vs
0, w, 0, h, 1, 1, 1, 1,
w, h, w, h, 1, 1, 1, 1,
}
} }
func TestClear(t *testing.T) { func TestClear(t *testing.T) {

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build ebitenginegldebug //go:build !playstation5 && ebitenginegldebug
package opengl package opengl

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build !ebitenginegldebug //go:build !playstation5 && !ebitenginegldebug
package opengl package opengl

View File

@ -73,20 +73,22 @@ func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderSrcImageCount]*Mipmap, verti
level := 0 level := 0
if !canSkipMipmap && srcs[0] != nil && canUseMipmap(srcs[0].imageType) { if !canSkipMipmap && srcs[0] != nil && canUseMipmap(srcs[0].imageType) {
level = math.MaxInt32 level = math.MaxInt32
for i := 0; i < len(indices)/3; i++ { for i := 0; i < len(indices); i += 3 {
const n = graphics.VertexFloatCount idx0 := indices[i]
dx0 := vertices[n*indices[3*i]+0] idx1 := indices[i+1]
dy0 := vertices[n*indices[3*i]+1] idx2 := indices[i+2]
sx0 := vertices[n*indices[3*i]+2] dx0 := vertices[graphics.VertexFloatCount*idx0]
sy0 := vertices[n*indices[3*i]+3] dy0 := vertices[graphics.VertexFloatCount*idx0+1]
dx1 := vertices[n*indices[3*i+1]+0] sx0 := vertices[graphics.VertexFloatCount*idx0+2]
dy1 := vertices[n*indices[3*i+1]+1] sy0 := vertices[graphics.VertexFloatCount*idx0+3]
sx1 := vertices[n*indices[3*i+1]+2] dx1 := vertices[graphics.VertexFloatCount*idx1]
sy1 := vertices[n*indices[3*i+1]+3] dy1 := vertices[graphics.VertexFloatCount*idx1+1]
dx2 := vertices[n*indices[3*i+2]+0] sx1 := vertices[graphics.VertexFloatCount*idx1+2]
dy2 := vertices[n*indices[3*i+2]+1] sy1 := vertices[graphics.VertexFloatCount*idx1+3]
sx2 := vertices[n*indices[3*i+2]+2] dx2 := vertices[graphics.VertexFloatCount*idx2]
sy2 := vertices[n*indices[3*i+2]+3] dy2 := vertices[graphics.VertexFloatCount*idx2+1]
sx2 := vertices[graphics.VertexFloatCount*idx2+2]
sy2 := vertices[graphics.VertexFloatCount*idx2+3]
if l := mipmapLevelFromDistance(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1); level > l { if l := mipmapLevelFromDistance(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1); level > l {
level = l level = l
} }
@ -109,11 +111,10 @@ func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderSrcImageCount]*Mipmap, verti
} }
if level != 0 { if level != 0 {
if img := src.level(level); img != nil { if img := src.level(level); img != nil {
const n = graphics.VertexFloatCount
s := float32(pow2(level)) s := float32(pow2(level))
for i := 0; i < len(vertices)/n; i++ { for i := 0; i < len(vertices); i += graphics.VertexFloatCount {
vertices[i*n+2] /= s vertices[i+2] /= s
vertices[i*n+3] /= s vertices[i+3] /= s
} }
imgs[i] = img imgs[i] = img
continue continue
@ -148,12 +149,10 @@ func (m *Mipmap) level(level int) *buffered.Image {
var src *buffered.Image var src *buffered.Image
vs := make([]float32, 4*graphics.VertexFloatCount) vs := make([]float32, 4*graphics.VertexFloatCount)
shader := atlas.NearestFilterShader
switch { switch {
case level == 1: case level == 1:
src = m.orig src = m.orig
graphics.QuadVertices(vs, 0, 0, float32(m.width), float32(m.height), 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1) graphics.QuadVerticesFromSrcAndMatrix(vs, 0, 0, float32(m.width), float32(m.height), 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
shader = atlas.LinearFilterShader
case level > 1: case level > 1:
src = m.level(level - 1) src = m.level(level - 1)
if src == nil { if src == nil {
@ -162,8 +161,7 @@ func (m *Mipmap) level(level int) *buffered.Image {
} }
w := sizeForLevel(m.width, level-1) w := sizeForLevel(m.width, level-1)
h := sizeForLevel(m.height, level-1) h := sizeForLevel(m.height, level-1)
graphics.QuadVertices(vs, 0, 0, float32(w), float32(h), 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1) graphics.QuadVerticesFromSrcAndMatrix(vs, 0, 0, float32(w), float32(h), 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
shader = atlas.LinearFilterShader
default: default:
panic(fmt.Sprintf("mipmap: invalid level: %d", level)) panic(fmt.Sprintf("mipmap: invalid level: %d", level))
} }
@ -186,7 +184,7 @@ func (m *Mipmap) level(level int) *buffered.Image {
s := buffered.NewImage(w2, h2, m.imageType) s := buffered.NewImage(w2, h2, m.imageType)
dstRegion := image.Rect(0, 0, w2, h2) dstRegion := image.Rect(0, 0, w2, h2)
s.DrawTriangles([graphics.ShaderSrcImageCount]*buffered.Image{src}, vs, is, graphicsdriver.BlendCopy, dstRegion, [graphics.ShaderSrcImageCount]image.Rectangle{}, shader, nil, graphicsdriver.FillRuleFillAll) s.DrawTriangles([graphics.ShaderSrcImageCount]*buffered.Image{src}, vs, is, graphicsdriver.BlendCopy, dstRegion, [graphics.ShaderSrcImageCount]image.Rectangle{}, atlas.LinearFilterShader, nil, graphicsdriver.FillRuleFillAll)
m.setImg(level, s) m.setImg(level, s)
return m.imgs[level] return m.imgs[level]

View File

@ -158,7 +158,7 @@ func (i *Image) Fill(r, g, b, a float32, region image.Rectangle) {
i.tmpVerticesForFill = make([]float32, 4*graphics.VertexFloatCount) i.tmpVerticesForFill = make([]float32, 4*graphics.VertexFloatCount)
} }
// i.tmpVerticesForFill can be reused as this is sent to DrawTriangles immediately. // i.tmpVerticesForFill can be reused as this is sent to DrawTriangles immediately.
graphics.QuadVertices( graphics.QuadVerticesFromSrcAndMatrix(
i.tmpVerticesForFill, i.tmpVerticesForFill,
1, 1, float32(i.ui.whiteImage.width-1), float32(i.ui.whiteImage.height-1), 1, 1, float32(i.ui.whiteImage.width-1), float32(i.ui.whiteImage.height-1),
float32(i.width), 0, 0, float32(i.height), 0, 0, float32(i.width), 0, 0, float32(i.height), 0, 0,
@ -235,7 +235,7 @@ func (i *bigOffscreenImage) drawTriangles(srcs [graphics.ShaderSrcImageCount]*Im
i.tmpVerticesForCopying = make([]float32, 4*graphics.VertexFloatCount) i.tmpVerticesForCopying = make([]float32, 4*graphics.VertexFloatCount)
} }
// i.tmpVerticesForCopying can be reused as this is sent to DrawTriangles immediately. // i.tmpVerticesForCopying can be reused as this is sent to DrawTriangles immediately.
graphics.QuadVertices( graphics.QuadVerticesFromSrcAndMatrix(
i.tmpVerticesForCopying, i.tmpVerticesForCopying,
float32(i.region.Min.X), float32(i.region.Min.Y), float32(i.region.Max.X), float32(i.region.Max.Y), float32(i.region.Min.X), float32(i.region.Min.Y), float32(i.region.Max.X), float32(i.region.Max.Y),
bigOffscreenScale, 0, 0, bigOffscreenScale, 0, 0, bigOffscreenScale, 0, 0, bigOffscreenScale, 0, 0,
@ -279,7 +279,7 @@ func (i *bigOffscreenImage) flush() {
i.tmpVerticesForFlushing = make([]float32, 4*graphics.VertexFloatCount) i.tmpVerticesForFlushing = make([]float32, 4*graphics.VertexFloatCount)
} }
// i.tmpVerticesForFlushing can be reused as this is sent to DrawTriangles in this function. // i.tmpVerticesForFlushing can be reused as this is sent to DrawTriangles in this function.
graphics.QuadVertices( graphics.QuadVerticesFromSrcAndMatrix(
i.tmpVerticesForFlushing, i.tmpVerticesForFlushing,
0, 0, float32(i.region.Dx()*bigOffscreenScale), float32(i.region.Dy()*bigOffscreenScale), 0, 0, float32(i.region.Dx()*bigOffscreenScale), float32(i.region.Dy()*bigOffscreenScale),
1.0/bigOffscreenScale, 0, 0, 1.0/bigOffscreenScale, float32(i.region.Min.X), float32(i.region.Min.Y), 1.0/bigOffscreenScale, 0, 0, 1.0/bigOffscreenScale, float32(i.region.Min.X), float32(i.region.Min.Y),