internal/atlas, internal/graphicsdriver: move the adjusting-pixel logic to atlas

Now pixels are adjusted even when the graphics driver doesn't have
high-precision floats, but this should not be problematic. This was
introduced at 9bff33472a, but the
adjusting way is much different from the current way.

Updates #879
Closes #1820
This commit is contained in:
Hajime Hoshi 2022-04-02 04:59:30 +09:00
parent 34e23f5256
commit 351ef9fbb7
2 changed files with 22 additions and 40 deletions

View File

@ -17,6 +17,7 @@ package atlas
import ( import (
"fmt" "fmt"
"image" "image"
"math"
"runtime" "runtime"
"sync" "sync"
@ -446,8 +447,8 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
swf, shf := float32(sw), float32(sh) swf, shf := float32(sw), float32(sh)
n := len(vertices) n := len(vertices)
for i := 0; i < n; i += graphics.VertexFloatNum { for i := 0; i < n; i += graphics.VertexFloatNum {
vertices[i] += dx vertices[i] = adjustDestinationPixel(vertices[i] + dx)
vertices[i+1] += dy vertices[i+1] = adjustDestinationPixel(vertices[i+1] + dy)
vertices[i+2] = (vertices[i+2] + oxf) / swf vertices[i+2] = (vertices[i+2] + oxf) / swf
vertices[i+3] = (vertices[i+3] + oyf) / shf vertices[i+3] = (vertices[i+3] + oyf) / shf
} }
@ -460,8 +461,8 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
} else { } else {
n := len(vertices) n := len(vertices)
for i := 0; i < n; i += graphics.VertexFloatNum { for i := 0; i < n; i += graphics.VertexFloatNum {
vertices[i] += dx vertices[i] = adjustDestinationPixel(vertices[i] + dx)
vertices[i+1] += dy vertices[i+1] = adjustDestinationPixel(vertices[i+1] + dy)
} }
} }
@ -847,3 +848,20 @@ func DumpImages(graphicsDriver graphicsdriver.Graphics, dir string) error {
defer backendsM.Unlock() defer backendsM.Unlock()
return restorable.DumpImages(graphicsDriver, dir) return restorable.DumpImages(graphicsDriver, dir)
} }
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.
ix := float32(math.Floor(float64(x)))
frac := x - ix
switch {
case frac < 3.0/16.0:
return ix
case frac < 8.0/16.0:
return ix + 5.0/16.0
case frac < 13.0/16.0:
return ix + 11.0/16.0
default:
return ix + 16.0/16.0
}
}

View File

@ -208,42 +208,6 @@ func (q *commandQueue) flush(graphicsDriver graphicsdriver.Graphics) error {
vs := q.vertices vs := q.vertices
debug.Logf("Graphics commands:\n") debug.Logf("Graphics commands:\n")
if graphicsDriver.HasHighPrecisionFloat() {
n := q.nvertices / graphics.VertexFloatNum
for i := 0; i < n; i++ {
idx := i * graphics.VertexFloatNum
// Avoid the center of the pixel, which is problematic (#929, #1171).
// Instead, align the vertices with about 1/3 pixels.
x := vs[idx]
y := vs[idx+1]
ix := float32(math.Floor(float64(x)))
iy := float32(math.Floor(float64(y)))
fracx := x - ix
fracy := y - iy
switch {
case fracx < 3.0/16.0:
vs[idx] = ix
case fracx < 8.0/16.0:
vs[idx] = ix + 5.0/16.0
case fracx < 13.0/16.0:
vs[idx] = ix + 11.0/16.0
default:
vs[idx] = ix + 16.0/16.0
}
switch {
case fracy < 3.0/16.0:
vs[idx+1] = iy
case fracy < 8.0/16.0:
vs[idx+1] = iy + 5.0/16.0
case fracy < 13.0/16.0:
vs[idx+1] = iy + 11.0/16.0
default:
vs[idx+1] = iy + 16.0/16.0
}
}
}
if err := graphicsDriver.Begin(); err != nil { if err := graphicsDriver.Begin(); err != nil {
return err return err
} }