mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
ebiten: Bug fix: Fix the texel calculation
In shaders, texCoord is always in texture0's texels. Convert them at imageNTextureAt functions correctly. Fixes #1290
This commit is contained in:
parent
69f87d5fd1
commit
609a3c4e22
@ -26,14 +26,14 @@ const (
|
|||||||
PreservedUniformVariablesNum = 1 + // the destination texture size
|
PreservedUniformVariablesNum = 1 + // the destination texture size
|
||||||
1 + // the texture sizes array
|
1 + // the texture sizes array
|
||||||
1 + // the offsets array of the second and the following images
|
1 + // the offsets array of the second and the following images
|
||||||
1 + // the texture source origin
|
1 + // the texture source region's origin
|
||||||
1 // the texture source sizes
|
1 // the texture source region's size
|
||||||
|
|
||||||
DestinationTextureSizeUniformVariableIndex = 0
|
DestinationTextureSizeUniformVariableIndex = 0
|
||||||
TextureSizesUniformVariableIndex = 1
|
TextureSizesUniformVariableIndex = 1
|
||||||
TextureSourceOffsetsUniformVariableIndex = 2
|
TextureSourceOffsetsUniformVariableIndex = 2
|
||||||
TextureSourceOriginUniformVariableIndex = 3
|
TextureSourceRegionOriginUniformVariableIndex = 3
|
||||||
TextureSourceSizesUniformVariableIndex = 4
|
TextureSourceRegionSizeUniformVariableIndex = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -167,7 +167,6 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
|
|||||||
sourceRegion.Y /= float32(h)
|
sourceRegion.Y /= float32(h)
|
||||||
sourceRegion.Width /= float32(w)
|
sourceRegion.Width /= float32(w)
|
||||||
sourceRegion.Height /= float32(h)
|
sourceRegion.Height /= float32(h)
|
||||||
// TODO: This doesn't work when the src image sizes are different.
|
|
||||||
for i := range offsets {
|
for i := range offsets {
|
||||||
offsets[i][0] /= float32(w)
|
offsets[i][0] /= float32(w)
|
||||||
offsets[i][1] /= float32(h)
|
offsets[i][1] /= float32(h)
|
||||||
|
@ -1029,30 +1029,13 @@ func (g *Graphics) DrawShader(dstID driver.ImageID, srcIDs [graphics.ShaderImage
|
|||||||
}
|
}
|
||||||
us[graphics.TextureSourceOffsetsUniformVariableIndex] = uoffsets
|
us[graphics.TextureSourceOffsetsUniformVariableIndex] = uoffsets
|
||||||
|
|
||||||
// Set the source origin of the first image.
|
// Set the source region's origin of texture0.
|
||||||
uorigin := []float32{float32(sourceRegion.X), float32(sourceRegion.Y)}
|
uorigin := []float32{float32(sourceRegion.X), float32(sourceRegion.Y)}
|
||||||
us[graphics.TextureSourceOriginUniformVariableIndex] = uorigin
|
us[graphics.TextureSourceRegionOriginUniformVariableIndex] = uorigin
|
||||||
|
|
||||||
// Set the source sizes.
|
// Set the source region's size of texture0.
|
||||||
ussizes := make([]float32, 2*len(srcs))
|
ussize := []float32{float32(sourceRegion.Width), float32(sourceRegion.Height)}
|
||||||
if srcs[0] != nil {
|
us[graphics.TextureSourceRegionSizeUniformVariableIndex] = ussize
|
||||||
w, h := sourceRegion.Width, sourceRegion.Height
|
|
||||||
bw, bh := srcs[0].internalSize()
|
|
||||||
for i, src := range srcs {
|
|
||||||
if i == 0 {
|
|
||||||
ussizes[2*i] = float32(w)
|
|
||||||
ussizes[2*i+1] = float32(h)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if src == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
tw, th := src.internalSize()
|
|
||||||
ussizes[2*i] = float32(w) * float32(bw) / float32(tw)
|
|
||||||
ussizes[2*i+1] = float32(h) * float32(bh) / float32(th)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
us[graphics.TextureSourceSizesUniformVariableIndex] = ussizes
|
|
||||||
|
|
||||||
// Set the additional uniform variables.
|
// Set the additional uniform variables.
|
||||||
for i, v := range uniforms {
|
for i, v := range uniforms {
|
||||||
|
@ -336,37 +336,17 @@ func (g *Graphics) DrawShader(dst driver.ImageID, srcs [graphics.ShaderImageNum]
|
|||||||
us[idx].typ = s.ir.Uniforms[idx]
|
us[idx].typ = s.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
origin := make([]float32, 2)
|
origin := []float32{float32(sourceRegion.X), float32(sourceRegion.Y)}
|
||||||
origin[0] = sourceRegion.X
|
const idx = graphics.TextureSourceRegionOriginUniformVariableIndex
|
||||||
origin[1] = sourceRegion.Y
|
|
||||||
const idx = graphics.TextureSourceOriginUniformVariableIndex
|
|
||||||
us[idx].name = fmt.Sprintf("U%d", idx)
|
us[idx].name = fmt.Sprintf("U%d", idx)
|
||||||
us[idx].value = origin
|
us[idx].value = origin
|
||||||
us[idx].typ = s.ir.Uniforms[idx]
|
us[idx].typ = s.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
sizes := make([]float32, 2*len(srcs))
|
size := []float32{float32(sourceRegion.Width), float32(sourceRegion.Height)}
|
||||||
if baseimg := g.images[srcs[0]]; baseimg != nil {
|
const idx = graphics.TextureSourceRegionSizeUniformVariableIndex
|
||||||
w, h := sourceRegion.Width, sourceRegion.Height
|
|
||||||
bw, bh := baseimg.framebufferSize()
|
|
||||||
for i, src := range srcs {
|
|
||||||
if i == 0 {
|
|
||||||
sizes[2*i] = float32(w)
|
|
||||||
sizes[2*i+1] = float32(h)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
img := g.images[src]
|
|
||||||
if img == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
tw, th := img.framebufferSize()
|
|
||||||
sizes[2*i] = float32(w) * float32(bw) / float32(tw)
|
|
||||||
sizes[2*i+1] = float32(h) * float32(bh) / float32(th)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const idx = graphics.TextureSourceSizesUniformVariableIndex
|
|
||||||
us[idx].name = fmt.Sprintf("U%d", idx)
|
us[idx].name = fmt.Sprintf("U%d", idx)
|
||||||
us[idx].value = sizes
|
us[idx].value = size
|
||||||
us[idx].typ = s.ir.Uniforms[idx]
|
us[idx].typ = s.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,12 +241,8 @@ func defaultProgram() shaderir.Program {
|
|||||||
}
|
}
|
||||||
// Source region origin
|
// Source region origin
|
||||||
p.Uniforms[3] = shaderir.Type{Main: shaderir.Vec2}
|
p.Uniforms[3] = shaderir.Type{Main: shaderir.Vec2}
|
||||||
// Source region sizes
|
// Source region size
|
||||||
p.Uniforms[4] = shaderir.Type{
|
p.Uniforms[4] = shaderir.Type{Main: shaderir.Vec2}
|
||||||
Main: shaderir.Array,
|
|
||||||
Length: graphics.ShaderImageNum,
|
|
||||||
Sub: []shaderir.Type{{Main: shaderir.Vec2}},
|
|
||||||
}
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
shader.go
24
shader.go
@ -49,30 +49,38 @@ func image%[1]dTextureSize() vec2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shaderSuffix += fmt.Sprintf(`
|
shaderSuffix += fmt.Sprintf(`
|
||||||
|
// The unit is texture0's texels.
|
||||||
var __textureSourceOffsets [%[1]d]vec2
|
var __textureSourceOffsets [%[1]d]vec2
|
||||||
|
|
||||||
|
// The unit is texture0's texels.
|
||||||
var __textureSourceOrigin vec2
|
var __textureSourceOrigin vec2
|
||||||
var __textureSourceSizes [%[2]d]vec2
|
|
||||||
|
// The unit is texture0's texels.
|
||||||
|
var __textureSourceSize vec2
|
||||||
`, graphics.ShaderImageNum-1, graphics.ShaderImageNum)
|
`, graphics.ShaderImageNum-1, graphics.ShaderImageNum)
|
||||||
|
|
||||||
for i := 0; i < graphics.ShaderImageNum; i++ {
|
for i := 0; i < graphics.ShaderImageNum; i++ {
|
||||||
var offset string
|
pos := "pos"
|
||||||
if i >= 1 {
|
if i >= 1 {
|
||||||
offset = fmt.Sprintf(" + __textureSourceOffsets[%d]", i-1)
|
// Convert the position in texture0's texels to the target texture texels.
|
||||||
|
pos = fmt.Sprintf("(pos + __textureSourceOffsets[%d]) * __textureSizes[0] / __textureSizes[%d]", i-1, i)
|
||||||
}
|
}
|
||||||
// __t%d is a special variable for a texture variable.
|
// __t%d is a special variable for a texture variable.
|
||||||
shaderSuffix += fmt.Sprintf(`
|
shaderSuffix += fmt.Sprintf(`
|
||||||
func image%[1]dTextureAt(pos vec2) vec4 {
|
func image%[1]dTextureAt(pos vec2) vec4 {
|
||||||
return texture2D(__t%[1]d, pos%[2]s)
|
// pos is the position in texture0's texels.
|
||||||
|
return texture2D(__t%[1]d, %[2]s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func image%[1]dTextureBoundsAt(pos vec2) vec4 {
|
func image%[1]dTextureBoundsAt(pos vec2) vec4 {
|
||||||
return texture2D(__t%[1]d, pos%[2]s) *
|
// pos is the position in texture0's texels.
|
||||||
|
return texture2D(__t%[1]d, %[2]s) *
|
||||||
step(__textureSourceOrigin.x, pos.x) *
|
step(__textureSourceOrigin.x, pos.x) *
|
||||||
(1 - step(__textureSourceOrigin.x + __textureSourceSizes[%[1]d].x, pos.x)) *
|
(1 - step(__textureSourceOrigin.x + __textureSourceSize.x, pos.x)) *
|
||||||
step(__textureSourceOrigin.y, pos.y) *
|
step(__textureSourceOrigin.y, pos.y) *
|
||||||
(1 - step(__textureSourceOrigin.y + __textureSourceSizes[%[1]d].y, pos.y))
|
(1 - step(__textureSourceOrigin.y + __textureSourceSize.y, pos.y))
|
||||||
}
|
}
|
||||||
`, i, offset)
|
`, i, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderSuffix += `
|
shaderSuffix += `
|
||||||
|
Loading…
Reference in New Issue
Block a user