mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
graphicsdriver/opengl: Ignore non-existent uniform locations
Shader users should not have to care about the existence of uniform variables. Updates #1168
This commit is contained in:
parent
f80719ef9a
commit
1c980a16f5
@ -71,6 +71,7 @@ type programID uint32
|
||||
const (
|
||||
invalidTexture = 0
|
||||
invalidFramebuffer = (1 << 32) - 1
|
||||
invalidUniform = -1
|
||||
)
|
||||
|
||||
func getProgramID(p program) programID {
|
||||
@ -383,31 +384,45 @@ func (c *context) getUniformLocationImpl(p program, location string) uniformLoca
|
||||
l, free := gl.Strs(location + "\x00")
|
||||
uniform := uniformLocation(gl.GetUniformLocation(uint32(p), *l))
|
||||
free()
|
||||
if uniform == -1 {
|
||||
panic("opengl: invalid uniform location: " + location)
|
||||
}
|
||||
return uniform
|
||||
}
|
||||
|
||||
func (c *context) uniformInt(p program, location string, v int) {
|
||||
func (c *context) uniformInt(p program, location string, v int) bool {
|
||||
var r bool
|
||||
_ = c.t.Call(func() error {
|
||||
l := int32(c.locationCache.GetUniformLocation(c, p, location))
|
||||
if l == invalidUniform {
|
||||
return nil
|
||||
}
|
||||
r = true
|
||||
gl.Uniform1i(l, int32(v))
|
||||
return nil
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
func (c *context) uniformFloat(p program, location string, v float32) {
|
||||
func (c *context) uniformFloat(p program, location string, v float32) bool {
|
||||
var r bool
|
||||
_ = c.t.Call(func() error {
|
||||
l := int32(c.locationCache.GetUniformLocation(c, p, location))
|
||||
if l == invalidUniform {
|
||||
return nil
|
||||
}
|
||||
r = true
|
||||
gl.Uniform1f(l, v)
|
||||
return nil
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
func (c *context) uniformFloats(p program, location string, v []float32) {
|
||||
func (c *context) uniformFloats(p program, location string, v []float32) bool {
|
||||
var r bool
|
||||
_ = c.t.Call(func() error {
|
||||
l := int32(c.locationCache.GetUniformLocation(c, p, location))
|
||||
if l == invalidUniform {
|
||||
return nil
|
||||
}
|
||||
r = true
|
||||
switch len(v) {
|
||||
case 2:
|
||||
gl.Uniform2fv(l, 1, (*float32)(gl.Ptr(v)))
|
||||
@ -420,6 +435,7 @@ func (c *context) uniformFloats(p program, location string, v []float32) {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
func (c *context) vertexAttribPointer(p program, index int, size int, dataType dataType, stride int, offset int) {
|
||||
|
@ -67,6 +67,8 @@ func (p program) equal(rhs program) bool {
|
||||
|
||||
var InvalidTexture = textureNative(js.Null())
|
||||
|
||||
var invalidUniform = uniformLocation(js.Null())
|
||||
|
||||
func getProgramID(p program) programID {
|
||||
return p.id
|
||||
}
|
||||
@ -423,24 +425,35 @@ func (c *context) getUniformLocationImpl(p program, location string) uniformLoca
|
||||
return uniformLocation(gl.Call("getUniformLocation", p.value, location))
|
||||
}
|
||||
|
||||
func (c *context) uniformInt(p program, location string, v int) {
|
||||
func (c *context) uniformInt(p program, location string, v int) bool {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||
if l.equal(invalidUniform) {
|
||||
return false
|
||||
}
|
||||
gl.Call("uniform1i", js.Value(l), v)
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) uniformFloat(p program, location string, v float32) {
|
||||
func (c *context) uniformFloat(p program, location string, v float32) bool {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||
if l.equal(invalidUniform) {
|
||||
return false
|
||||
}
|
||||
gl.Call("uniform1f", js.Value(l), v)
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) uniformFloats(p program, location string, v []float32) {
|
||||
func (c *context) uniformFloats(p program, location string, v []float32) bool {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||
if l.equal(invalidUniform) {
|
||||
return false
|
||||
}
|
||||
switch len(v) {
|
||||
case 2:
|
||||
gl.Call("uniform2f", js.Value(l), v[0], v[1])
|
||||
@ -454,6 +467,7 @@ func (c *context) uniformFloats(p program, location string, v []float32) {
|
||||
default:
|
||||
panic(fmt.Sprintf("opengl: invalid uniform floats num: %d", len(v)))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) vertexAttribPointer(p program, index int, size int, dataType dataType, stride int, offset int) {
|
||||
|
@ -69,6 +69,7 @@ type programID uint32
|
||||
var (
|
||||
invalidTexture = textureNative(mgl.Texture{})
|
||||
invalidFramebuffer = framebufferNative(mgl.Framebuffer{(1 << 32) - 1})
|
||||
invalidUniform = uniformLocation(mgl.Uniform{-1})
|
||||
)
|
||||
|
||||
func getProgramID(p program) programID {
|
||||
@ -286,35 +287,46 @@ func (c *context) deleteProgram(p program) {
|
||||
func (c *context) getUniformLocationImpl(p program, location string) uniformLocation {
|
||||
gl := c.gl
|
||||
u := uniformLocation(gl.GetUniformLocation(mgl.Program(p), location))
|
||||
if u.Value == -1 {
|
||||
panic("invalid uniform location: " + location)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func (c *context) uniformInt(p program, location string, v int) {
|
||||
func (c *context) uniformInt(p program, location string, v int) bool {
|
||||
gl := c.gl
|
||||
gl.Uniform1i(mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location)), v)
|
||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||
if l == invalidUniform {
|
||||
return false
|
||||
}
|
||||
gl.Uniform1i(mgl.Uniform(l), v)
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) uniformFloat(p program, location string, v float32) {
|
||||
func (c *context) uniformFloat(p program, location string, v float32) bool {
|
||||
gl := c.gl
|
||||
gl.Uniform1f(mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location)), v)
|
||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||
if l == invalidUniform {
|
||||
return false
|
||||
}
|
||||
gl.Uniform1f(mgl.Uniform(l), v)
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) uniformFloats(p program, location string, v []float32) {
|
||||
func (c *context) uniformFloats(p program, location string, v []float32) bool {
|
||||
gl := c.gl
|
||||
l := mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location))
|
||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||
if l == invalidUniform {
|
||||
return false
|
||||
}
|
||||
switch len(v) {
|
||||
case 2:
|
||||
gl.Uniform2fv(l, v)
|
||||
gl.Uniform2fv(mgl.Uniform(l), v)
|
||||
case 4:
|
||||
gl.Uniform4fv(l, v)
|
||||
gl.Uniform4fv(mgl.Uniform(l), v)
|
||||
case 16:
|
||||
gl.UniformMatrix4fv(l, v)
|
||||
gl.UniformMatrix4fv(mgl.Uniform(l), v)
|
||||
default:
|
||||
panic(fmt.Sprintf("opengl: invalid uniform floats num: %d", len(v)))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) vertexAttribPointer(p program, index int, size int, dataType dataType, stride int, offset int) {
|
||||
|
@ -266,6 +266,7 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable) error
|
||||
if ok && cached == v {
|
||||
continue
|
||||
}
|
||||
// TODO: Remember whether the location is available or not.
|
||||
g.context.uniformFloat(program, u.name, v)
|
||||
g.state.lastUniforms[u.name] = v
|
||||
case []float32:
|
||||
@ -283,9 +284,6 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable) error
|
||||
g.state.lastActiveTexture = u.textureIndex
|
||||
}
|
||||
g.context.bindTexture(v)
|
||||
case nil:
|
||||
// TODO: Rather than using nil for skipping, check the availablity of locations at e.g.,
|
||||
// uniformFloats and ignore the error for unavailability.
|
||||
default:
|
||||
return fmt.Errorf("opengl: unexpected uniform value: %v", u.value)
|
||||
}
|
||||
|
@ -112,18 +112,15 @@ func TestShaderMultipleSources(t *testing.T) {
|
||||
|
||||
ir := etesting.ShaderProgramImages(3)
|
||||
s := NewShader(&ir)
|
||||
// TODO: Now GLSL's optimization eliminates unused uniform variables by the program. Now nils are given,
|
||||
// but it is strange to care about optimization from users. We should ignore the error when the location is
|
||||
// not available.
|
||||
us := []interface{}{
|
||||
[]float32{1, 1},
|
||||
srcs[0],
|
||||
srcs[1],
|
||||
nil, // []float32{1, 1},
|
||||
nil, // []float32{0, 0, 1, 1},
|
||||
[]float32{1, 1},
|
||||
[]float32{0, 0, 1, 1},
|
||||
srcs[2],
|
||||
nil, // []float32{1, 1},
|
||||
nil, // []float32{0, 0, 1, 1},
|
||||
[]float32{1, 1},
|
||||
[]float32{0, 0, 1, 1},
|
||||
}
|
||||
dst.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user