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())
cr, cg, cb, ca = options.ColorScale.apply(cr, cg, cb, ca)
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()
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)
// 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+width), float32(srcRegions[0].Min.Y+height),
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) {
img0 := ebiten.NewImage(2, 2)
img0.WritePixels([]byte{

View File

@ -43,16 +43,6 @@ func min(a, b int) int {
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()) {
deferredM.Lock()
defer deferredM.Unlock()
@ -149,7 +139,8 @@ func (b *backend) extendIfNeeded(width, height int) {
srcs := [graphics.ShaderSrcImageCount]*graphicscommand.Image{b.image}
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()
dr := image.Rect(0, 0, sw, sh)
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) {
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()
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)
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()
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)
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()
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)

View File

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

View File

@ -246,45 +246,51 @@ func (i *Image) syncPixelsIfNeeded() {
cbf := float32(c[2]) / 0xff
caf := float32(c[3]) / 0xff
vs[graphics.VertexFloatCount*4*idx] = dx
vs[graphics.VertexFloatCount*4*idx+1] = dy
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
vidx := 4 * idx
iidx := 6 * idx
is[6*idx] = uint32(4 * idx)
is[6*idx+1] = uint32(4*idx + 1)
is[6*idx+2] = uint32(4*idx + 2)
is[6*idx+3] = uint32(4*idx + 1)
is[6*idx+4] = uint32(4*idx + 2)
is[6*idx+5] = uint32(4*idx + 3)
vs[graphics.VertexFloatCount*vidx] = dx
vs[graphics.VertexFloatCount*vidx+1] = dy
vs[graphics.VertexFloatCount*vidx+2] = sx
vs[graphics.VertexFloatCount*vidx+3] = sy
vs[graphics.VertexFloatCount*vidx+4] = crf
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++
}

View File

@ -52,7 +52,7 @@ func TestUnsyncedPixels(t *testing.T) {
// Flush unsynced pixel cache.
src := buffered.NewImage(16, 16, atlas.ImageTypeRegular)
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()
dr := 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
}
// QuadVertices sets a float32 slice for a quadrangle.
// QuadVertices sets a slice that never overlaps with other slices returned this function,
// 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) {
// QuadVerticesFromSrcAndMatrix sets a float32 slice for a quadrangle.
func QuadVerticesFromSrcAndMatrix(dst []float32, sx0, sy0, sx1, sy1 float32, a, b, c, d, tx, ty float32, cr, cg, cb, ca float32) {
x := sx1 - sx0
y := sy1 - sy0
ax, by, cx, dy := a*x, b*y, c*x, d*y
u0, v0, u1, v1 := sx0, sy0, sx1, sy1
// This function is very performance-sensitive and implement in a very dumb way.
// Remove the boundary check.
dst = dst[:4*VertexFloatCount]
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[7] = ca
dst[8] = adjustDestinationPixel(ax + tx)
dst[9] = adjustDestinationPixel(cx + ty)
dst[10] = u1
dst[11] = v0
dst[12] = cr
dst[13] = cg
dst[14] = cb
dst[15] = ca
dst[VertexFloatCount] = adjustDestinationPixel(ax + tx)
dst[VertexFloatCount+1] = adjustDestinationPixel(cx + ty)
dst[VertexFloatCount+2] = u1
dst[VertexFloatCount+3] = v0
dst[VertexFloatCount+4] = cr
dst[VertexFloatCount+5] = cg
dst[VertexFloatCount+6] = cb
dst[VertexFloatCount+7] = ca
dst[16] = adjustDestinationPixel(by + tx)
dst[17] = adjustDestinationPixel(dy + ty)
dst[18] = u0
dst[19] = v1
dst[20] = cr
dst[21] = cg
dst[22] = cb
dst[23] = ca
dst[2*VertexFloatCount] = adjustDestinationPixel(by + tx)
dst[2*VertexFloatCount+1] = adjustDestinationPixel(dy + ty)
dst[2*VertexFloatCount+2] = u0
dst[2*VertexFloatCount+3] = v1
dst[2*VertexFloatCount+4] = cr
dst[2*VertexFloatCount+5] = cg
dst[2*VertexFloatCount+6] = cb
dst[2*VertexFloatCount+7] = ca
dst[24] = adjustDestinationPixel(ax + by + tx)
dst[25] = adjustDestinationPixel(cx + dy + ty)
dst[26] = u1
dst[27] = v1
dst[28] = cr
dst[29] = cg
dst[30] = cb
dst[31] = ca
dst[3*VertexFloatCount] = adjustDestinationPixel(ax + by + tx)
dst[3*VertexFloatCount+1] = adjustDestinationPixel(cx + dy + ty)
dst[3*VertexFloatCount+2] = u1
dst[3*VertexFloatCount+3] = v1
dst[3*VertexFloatCount+4] = cr
dst[3*VertexFloatCount+5] = cg
dst[3*VertexFloatCount+6] = cb
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 {

View File

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

View File

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

View File

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

View File

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

View File

@ -73,20 +73,22 @@ func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderSrcImageCount]*Mipmap, verti
level := 0
if !canSkipMipmap && srcs[0] != nil && canUseMipmap(srcs[0].imageType) {
level = math.MaxInt32
for i := 0; i < len(indices)/3; i++ {
const n = graphics.VertexFloatCount
dx0 := vertices[n*indices[3*i]+0]
dy0 := vertices[n*indices[3*i]+1]
sx0 := vertices[n*indices[3*i]+2]
sy0 := vertices[n*indices[3*i]+3]
dx1 := vertices[n*indices[3*i+1]+0]
dy1 := vertices[n*indices[3*i+1]+1]
sx1 := vertices[n*indices[3*i+1]+2]
sy1 := vertices[n*indices[3*i+1]+3]
dx2 := vertices[n*indices[3*i+2]+0]
dy2 := vertices[n*indices[3*i+2]+1]
sx2 := vertices[n*indices[3*i+2]+2]
sy2 := vertices[n*indices[3*i+2]+3]
for i := 0; i < len(indices); i += 3 {
idx0 := indices[i]
idx1 := indices[i+1]
idx2 := indices[i+2]
dx0 := vertices[graphics.VertexFloatCount*idx0]
dy0 := vertices[graphics.VertexFloatCount*idx0+1]
sx0 := vertices[graphics.VertexFloatCount*idx0+2]
sy0 := vertices[graphics.VertexFloatCount*idx0+3]
dx1 := vertices[graphics.VertexFloatCount*idx1]
dy1 := vertices[graphics.VertexFloatCount*idx1+1]
sx1 := vertices[graphics.VertexFloatCount*idx1+2]
sy1 := vertices[graphics.VertexFloatCount*idx1+3]
dx2 := vertices[graphics.VertexFloatCount*idx2]
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 {
level = l
}
@ -109,11 +111,10 @@ func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderSrcImageCount]*Mipmap, verti
}
if level != 0 {
if img := src.level(level); img != nil {
const n = graphics.VertexFloatCount
s := float32(pow2(level))
for i := 0; i < len(vertices)/n; i++ {
vertices[i*n+2] /= s
vertices[i*n+3] /= s
for i := 0; i < len(vertices); i += graphics.VertexFloatCount {
vertices[i+2] /= s
vertices[i+3] /= s
}
imgs[i] = img
continue
@ -148,12 +149,10 @@ func (m *Mipmap) level(level int) *buffered.Image {
var src *buffered.Image
vs := make([]float32, 4*graphics.VertexFloatCount)
shader := atlas.NearestFilterShader
switch {
case level == 1:
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)
shader = atlas.LinearFilterShader
graphics.QuadVerticesFromSrcAndMatrix(vs, 0, 0, float32(m.width), float32(m.height), 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
case level > 1:
src = m.level(level - 1)
if src == nil {
@ -162,8 +161,7 @@ func (m *Mipmap) level(level int) *buffered.Image {
}
w := sizeForLevel(m.width, 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)
shader = atlas.LinearFilterShader
graphics.QuadVerticesFromSrcAndMatrix(vs, 0, 0, float32(w), float32(h), 0.5, 0, 0, 0.5, 0, 0, 1, 1, 1, 1)
default:
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)
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)
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 can be reused as this is sent to DrawTriangles immediately.
graphics.QuadVertices(
graphics.QuadVerticesFromSrcAndMatrix(
i.tmpVerticesForFill,
1, 1, float32(i.ui.whiteImage.width-1), float32(i.ui.whiteImage.height-1),
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 can be reused as this is sent to DrawTriangles immediately.
graphics.QuadVertices(
graphics.QuadVerticesFromSrcAndMatrix(
i.tmpVerticesForCopying,
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,
@ -279,7 +279,7 @@ func (i *bigOffscreenImage) flush() {
i.tmpVerticesForFlushing = make([]float32, 4*graphics.VertexFloatCount)
}
// i.tmpVerticesForFlushing can be reused as this is sent to DrawTriangles in this function.
graphics.QuadVertices(
graphics.QuadVerticesFromSrcAndMatrix(
i.tmpVerticesForFlushing,
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),