mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/graphics: unify QuadVertices
This is a preparation for adding members to Vertex. Updates #2640
This commit is contained in:
parent
6cd00f3b88
commit
b6ab7a10c1
4
image.go
4
image.go
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)}
|
||||
|
@ -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)
|
||||
@ -99,6 +99,53 @@ func QuadVertices(dst []float32, sx0, sy0, sx1, sy1 float32, a, b, c, d, tx, ty
|
||||
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 {
|
||||
// Avoid the center of the pixel, which is problematic (#929, #1171).
|
||||
// Instead, align the vertices with about 1/3 pixels.
|
||||
|
@ -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) {
|
||||
|
@ -152,7 +152,7 @@ func (m *Mipmap) level(level int) *buffered.Image {
|
||||
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)
|
||||
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 {
|
||||
@ -161,7 +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)
|
||||
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))
|
||||
}
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user