diff --git a/internal/graphicsdriver/opengl/program.go b/internal/graphicsdriver/opengl/program.go index 655b2d7f6..63b25c8b3 100644 --- a/internal/graphicsdriver/opengl/program.go +++ b/internal/graphicsdriver/opengl/program.go @@ -284,17 +284,43 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textu } } + type activatedTexture struct { + textureNative textureNative + index int + } + + // textureNative cannot be a map key unfortunately. + textureToActivatedTexture := []activatedTexture{} + var idx int +loop: for i, t := range textures { if !t.valid { continue } - g.context.uniformInt(program, fmt.Sprintf("T%d", i), i) - if g.state.lastActiveTexture != i { - g.context.activeTexture(i) - g.state.lastActiveTexture = i + + // If the texture is already bound, set the texture variable to point to the texture. + // Rebinding the same texture seems problematic (#1193). + for _, at := range textureToActivatedTexture { + if t.native.equal(at.textureNative) { + g.context.uniformInt(program, fmt.Sprintf("T%d", i), at.index) + continue loop + } } + + textureToActivatedTexture = append(textureToActivatedTexture, activatedTexture{ + textureNative: t.native, + index: idx, + }) + g.context.uniformInt(program, fmt.Sprintf("T%d", i), idx) + if g.state.lastActiveTexture != idx { + g.context.activeTexture(idx) + g.state.lastActiveTexture = idx + } + // Apparently, a texture must be bound every time. The cache is not used here. g.context.bindTexture(t.native) + + idx++ } return nil diff --git a/internal/restorable/shader_test.go b/internal/restorable/shader_test.go index 1c751f6f6..245d864e9 100644 --- a/internal/restorable/shader_test.go +++ b/internal/restorable/shader_test.go @@ -130,13 +130,13 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) { t.Skip("shader is not available on this environment") } - var srcs [graphics.ShaderImageNum]*Image - srcs[0] = NewImage(3, 1, false) - srcs[0].ReplacePixels([]byte{ + src := NewImage(3, 1, false) + src.ReplacePixels([]byte{ 0x40, 0, 0, 0xff, 0, 0x80, 0, 0xff, 0, 0, 0xc0, 0xff, }, 0, 0, 3, 1) + srcs := [graphics.ShaderImageNum]*Image{src, src, src} dst := NewImage(1, 1, false)