mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
graphicsdriver/opengl: Pass uniform values to useProgram
This commit is contained in:
parent
84e2c6f994
commit
ff311dd564
@ -113,13 +113,52 @@ func (g *Graphics) SetVertices(vertices []float32, indices []uint16) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
||||||
|
destination := g.state.destination
|
||||||
|
if destination == nil {
|
||||||
|
panic("destination image is not set")
|
||||||
|
}
|
||||||
|
source := g.state.source
|
||||||
|
if source == nil {
|
||||||
|
panic("source image is not set")
|
||||||
|
}
|
||||||
|
|
||||||
g.drawCalled = true
|
g.drawCalled = true
|
||||||
|
|
||||||
g.context.blendFunc(mode)
|
if err := destination.setViewport(); err != nil {
|
||||||
|
|
||||||
if err := g.useProgram(colorM, filter, address); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
g.context.blendFunc(mode)
|
||||||
|
|
||||||
|
program := g.state.programs[programKey{
|
||||||
|
useColorM: colorM != nil,
|
||||||
|
filter: filter,
|
||||||
|
address: address,
|
||||||
|
}]
|
||||||
|
|
||||||
|
uniforms := map[string][]float32{}
|
||||||
|
|
||||||
|
vw := destination.framebuffer.width
|
||||||
|
vh := destination.framebuffer.height
|
||||||
|
uniforms["viewport_size"] = []float32{float32(vw), float32(vh)}
|
||||||
|
|
||||||
|
if colorM != nil {
|
||||||
|
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
||||||
|
esBody, esTranslate := colorM.UnsafeElements()
|
||||||
|
uniforms["color_matrix_body"] = esBody
|
||||||
|
uniforms["color_matrix_translation"] = esTranslate
|
||||||
|
}
|
||||||
|
|
||||||
|
if filter != driver.FilterNearest {
|
||||||
|
srcW, srcH := source.width, source.height
|
||||||
|
sw := graphics.InternalImageSize(srcW)
|
||||||
|
sh := graphics.InternalImageSize(srcH)
|
||||||
|
uniforms["source_size"] = []float32{float32(sw), float32(sh)}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.useProgram(program, uniforms, filter); err != nil {
|
||||||
|
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).
|
||||||
|
@ -17,7 +17,6 @@ package opengl
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/affine"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/driver"
|
"github.com/hajimehoshi/ebiten/internal/driver"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/internal/web"
|
"github.com/hajimehoshi/ebiten/internal/web"
|
||||||
@ -241,27 +240,7 @@ func areSameFloat32Array(a, b []float32) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// useProgram uses the program (programTexture).
|
// useProgram uses the program (programTexture).
|
||||||
func (g *Graphics) useProgram(colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
func (g *Graphics) useProgram(program program, uniforms map[string][]float32, filter driver.Filter) error {
|
||||||
destination := g.state.destination
|
|
||||||
if destination == nil {
|
|
||||||
panic("destination image is not set")
|
|
||||||
}
|
|
||||||
source := g.state.source
|
|
||||||
if source == nil {
|
|
||||||
panic("source image is not set")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := destination.setViewport(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
dstW := destination.width
|
|
||||||
srcW, srcH := source.width, source.height
|
|
||||||
|
|
||||||
program := g.state.programs[programKey{
|
|
||||||
useColorM: colorM != nil,
|
|
||||||
filter: filter,
|
|
||||||
address: address,
|
|
||||||
}]
|
|
||||||
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) {
|
||||||
@ -275,46 +254,22 @@ func (g *Graphics) useProgram(colorM *affine.ColorM, filter driver.Filter, addre
|
|||||||
g.state.lastUniforms = map[string][]float32{}
|
g.state.lastUniforms = map[string][]float32{}
|
||||||
}
|
}
|
||||||
|
|
||||||
vw := destination.framebuffer.width
|
for key, u := range uniforms {
|
||||||
vh := destination.framebuffer.height
|
if areSameFloat32Array(g.state.lastUniforms[key], u) {
|
||||||
vs := []float32{float32(vw), float32(vh)}
|
continue
|
||||||
if !areSameFloat32Array(g.state.lastUniforms["viewport_size"], vs) {
|
|
||||||
g.context.uniformFloats(program, "viewport_size", vs)
|
|
||||||
g.state.lastUniforms["viewport_size"] = vs
|
|
||||||
}
|
|
||||||
|
|
||||||
if colorM != nil {
|
|
||||||
esBody, esTranslate := colorM.UnsafeElements()
|
|
||||||
if !areSameFloat32Array(g.state.lastUniforms["color_matrix_body"], esBody) {
|
|
||||||
g.context.uniformFloats(program, "color_matrix_body", esBody)
|
|
||||||
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
|
||||||
g.state.lastUniforms["color_matrix_body"] = esBody
|
|
||||||
}
|
|
||||||
if !areSameFloat32Array(g.state.lastUniforms["color_matrix_translation"], esTranslate) {
|
|
||||||
g.context.uniformFloats(program, "color_matrix_translation", esTranslate)
|
|
||||||
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
|
||||||
g.state.lastUniforms["color_matrix_translation"] = esTranslate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if filter != driver.FilterNearest {
|
|
||||||
sw := graphics.InternalImageSize(srcW)
|
|
||||||
sh := graphics.InternalImageSize(srcH)
|
|
||||||
s := []float32{float32(sw), float32(sh)}
|
|
||||||
if !areSameFloat32Array(g.state.lastUniforms["source_size"], s) {
|
|
||||||
g.context.uniformFloats(program, "source_size", s)
|
|
||||||
g.state.lastUniforms["source_size"] = s
|
|
||||||
}
|
}
|
||||||
|
g.context.uniformFloats(program, key, u)
|
||||||
|
g.state.lastUniforms[key] = u
|
||||||
}
|
}
|
||||||
|
|
||||||
if filter == driver.FilterScreen {
|
if filter == driver.FilterScreen {
|
||||||
scale := float32(dstW) / float32(srcW)
|
scale := float32(g.state.destination.width) / float32(g.state.source.width)
|
||||||
g.context.uniformFloat(program, "scale", scale)
|
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(source.textureNative)
|
g.context.bindTexture(g.state.source.textureNative)
|
||||||
|
|
||||||
g.state.source = nil
|
g.state.source = nil
|
||||||
g.state.destination = nil
|
g.state.destination = nil
|
||||||
|
Loading…
Reference in New Issue
Block a user