graphicsdriver/opengl: Treat a texture as a uniform variable

This commit is contained in:
Hajime Hoshi 2020-05-17 22:05:46 +09:00
parent 68ef41e256
commit 733c463e26
2 changed files with 13 additions and 7 deletions

View File

@ -156,15 +156,18 @@ func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode
} }
if filter == driver.FilterScreen { if filter == driver.FilterScreen {
scale := float32(g.state.destination.width) / float32(g.state.source.width) scale := float32(destination.width) / float32(source.width)
uniforms["scale"] = scale uniforms["scale"] = scale
} }
uniforms["texture"] = source.textureNative
if err := g.useProgram(program, uniforms); err != nil { if err := g.useProgram(program, uniforms); err != nil {
return err return err
} }
g.context.drawElements(indexLen, indexOffset*2) // 2 is uint16 size in bytes g.context.drawElements(indexLen, indexOffset*2) // 2 is uint16 size in bytes
// glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419), // glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419),
// but basically this pass the tests (esp. TestImageTooManyFill). // but basically this pass the tests (esp. TestImageTooManyFill).
// As glFlush() causes performance problems, this should be avoided as much as possible. // As glFlush() causes performance problems, this should be avoided as much as possible.

View File

@ -247,7 +247,6 @@ func (g *Graphics) useProgram(program program, uniforms map[string]interface{})
theArrayBufferLayout.enable(&g.context, program) theArrayBufferLayout.enable(&g.context, program)
g.context.bindBuffer(arrayBuffer, g.state.arrayBuffer) g.context.bindBuffer(arrayBuffer, g.state.arrayBuffer)
g.context.bindBuffer(elementArrayBuffer, g.state.elementArrayBuffer) g.context.bindBuffer(elementArrayBuffer, g.state.elementArrayBuffer)
g.context.uniformInt(program, "texture", 0)
} }
g.state.lastProgram = program g.state.lastProgram = program
@ -262,20 +261,24 @@ func (g *Graphics) useProgram(program program, uniforms map[string]interface{})
continue continue
} }
g.context.uniformFloat(program, key, u) g.context.uniformFloat(program, key, u)
g.state.lastUniforms[key] = u
case []float32: case []float32:
cached, ok := g.state.lastUniforms[key].([]float32) cached, ok := g.state.lastUniforms[key].([]float32)
if ok && areSameFloat32Array(cached, u) { if ok && areSameFloat32Array(cached, u) {
continue continue
} }
g.context.uniformFloats(program, key, u) g.context.uniformFloats(program, key, u)
g.state.lastUniforms[key] = u
case textureNative:
// Apparently, a texture must be bound every time. The cache is not used here.
// TODO: Use another value than 0 when binding multiple textures.
g.context.uniformInt(program, key, 0)
// We don't have to call gl.ActiveTexture here: GL_TEXTURE0 is the default active texture
// See also: https://www.opengl.org/sdk/docs/man2/xhtml/glActiveTexture.xml
g.context.bindTexture(u)
} }
g.state.lastUniforms[key] = u
} }
// We don't have to call gl.ActiveTexture here: GL_TEXTURE0 is the default active texture
// See also: https://www.opengl.org/sdk/docs/man2/xhtml/glActiveTexture.xml
g.context.bindTexture(g.state.source.textureNative)
g.state.source = nil g.state.source = nil
g.state.destination = nil g.state.destination = nil
return nil return nil