graphicsdriver/opengl: Integrate uniform variables

This commit is contained in:
Hajime Hoshi 2020-05-17 20:20:29 +09:00
parent ff311dd564
commit 68ef41e256
2 changed files with 24 additions and 14 deletions

View File

@ -135,7 +135,7 @@ func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode
address: address, address: address,
}] }]
uniforms := map[string][]float32{} uniforms := map[string]interface{}{}
vw := destination.framebuffer.width vw := destination.framebuffer.width
vh := destination.framebuffer.height vh := destination.framebuffer.height
@ -155,7 +155,12 @@ func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode
uniforms["source_size"] = []float32{float32(sw), float32(sh)} uniforms["source_size"] = []float32{float32(sw), float32(sh)}
} }
if err := g.useProgram(program, uniforms, filter); err != nil { if filter == driver.FilterScreen {
scale := float32(g.state.destination.width) / float32(g.state.source.width)
uniforms["scale"] = scale
}
if err := g.useProgram(program, uniforms); err != nil {
return err return err
} }

View File

@ -133,7 +133,7 @@ type openGLState struct {
programs map[programKey]program programs map[programKey]program
lastProgram program lastProgram program
lastUniforms map[string][]float32 lastUniforms map[string]interface{}
source *Image source *Image
destination *Image destination *Image
@ -151,7 +151,7 @@ func (s *openGLState) reset(context *context) error {
} }
s.lastProgram = zeroProgram s.lastProgram = zeroProgram
s.lastUniforms = map[string][]float32{} s.lastUniforms = map[string]interface{}{}
// When context lost happens, deleting programs or buffers is not necessary. // When context lost happens, deleting programs or buffers is not necessary.
// However, it is not assumed that reset is called only when context lost happens. // However, it is not assumed that reset is called only when context lost happens.
@ -240,7 +240,7 @@ func areSameFloat32Array(a, b []float32) bool {
} }
// useProgram uses the program (programTexture). // useProgram uses the program (programTexture).
func (g *Graphics) useProgram(program program, uniforms map[string][]float32, filter driver.Filter) error { func (g *Graphics) useProgram(program program, uniforms map[string]interface{}) error {
if !g.state.lastProgram.equal(program) { if !g.state.lastProgram.equal(program) {
g.context.useProgram(program) g.context.useProgram(program)
if g.state.lastProgram.equal(zeroProgram) { if g.state.lastProgram.equal(zeroProgram) {
@ -251,22 +251,27 @@ func (g *Graphics) useProgram(program program, uniforms map[string][]float32, fi
} }
g.state.lastProgram = program g.state.lastProgram = program
g.state.lastUniforms = map[string][]float32{} g.state.lastUniforms = map[string]interface{}{}
} }
for key, u := range uniforms { for key, u := range uniforms {
if areSameFloat32Array(g.state.lastUniforms[key], u) { switch u := u.(type) {
continue case float32:
cached, ok := g.state.lastUniforms[key].(float32)
if ok && cached == u {
continue
}
g.context.uniformFloat(program, key, u)
case []float32:
cached, ok := g.state.lastUniforms[key].([]float32)
if ok && areSameFloat32Array(cached, u) {
continue
}
g.context.uniformFloats(program, key, u)
} }
g.context.uniformFloats(program, key, u)
g.state.lastUniforms[key] = u g.state.lastUniforms[key] = u
} }
if filter == driver.FilterScreen {
scale := float32(g.state.destination.width) / float32(g.state.source.width)
g.context.uniformFloat(program, "scale", scale)
}
// We don't have to call gl.ActiveTexture here: GL_TEXTURE0 is the default active texture // 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 // See also: https://www.opengl.org/sdk/docs/man2/xhtml/glActiveTexture.xml
g.context.bindTexture(g.state.source.textureNative) g.context.bindTexture(g.state.source.textureNative)