mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
graphicsdriver/opengl: Use glBindAttribLocation instead of glGetAttribLocation
Attribute variables are often optimized out and it is really hard to prevent this. Instead of implicit indices of attribute variables, use explicit indices by glBindAttribLocation. Bug: #816
This commit is contained in:
parent
7ff99d3965
commit
09ca873c41
@ -311,7 +311,7 @@ func (c *context) deleteShader(s shader) {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *context) newProgram(shaders []shader) (program, error) {
|
||||
func (c *context) newProgram(shaders []shader, attributes []string) (program, error) {
|
||||
var pr program
|
||||
if err := mainthread.Run(func() error {
|
||||
p := gl.CreateProgram()
|
||||
@ -322,6 +322,13 @@ func (c *context) newProgram(shaders []shader) (program, error) {
|
||||
for _, shader := range shaders {
|
||||
gl.AttachShader(p, uint32(shader))
|
||||
}
|
||||
|
||||
for i, name := range attributes {
|
||||
l, free := gl.Strs(name + "\x00")
|
||||
gl.BindAttribLocation(p, uint32(i), *l)
|
||||
free()
|
||||
}
|
||||
|
||||
gl.LinkProgram(p)
|
||||
var v int32
|
||||
gl.GetProgramiv(p, gl.LINK_STATUS, &v)
|
||||
@ -396,36 +403,23 @@ func (c *context) uniformFloats(p program, location string, v []float32) {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *context) getAttribLocationImpl(p program, location string) attribLocation {
|
||||
l, free := gl.Strs(location + "\x00")
|
||||
attrib := attribLocation(gl.GetAttribLocation(uint32(p), *l))
|
||||
free()
|
||||
if attrib == -1 {
|
||||
panic("opengl: invalid attrib location: " + location)
|
||||
}
|
||||
return attrib
|
||||
}
|
||||
|
||||
func (c *context) vertexAttribPointer(p program, location string, size int, dataType dataType, stride int, offset int) {
|
||||
func (c *context) vertexAttribPointer(p program, index int, size int, dataType dataType, stride int, offset int) {
|
||||
_ = mainthread.Run(func() error {
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.VertexAttribPointer(uint32(l), int32(size), uint32(dataType), false, int32(stride), gl.PtrOffset(offset))
|
||||
gl.VertexAttribPointer(uint32(index), int32(size), uint32(dataType), false, int32(stride), gl.PtrOffset(offset))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (c *context) enableVertexAttribArray(p program, location string) {
|
||||
func (c *context) enableVertexAttribArray(p program, index int) {
|
||||
_ = mainthread.Run(func() error {
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.EnableVertexAttribArray(uint32(l))
|
||||
gl.EnableVertexAttribArray(uint32(index))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (c *context) disableVertexAttribArray(p program, location string) {
|
||||
func (c *context) disableVertexAttribArray(p program, index int) {
|
||||
_ = mainthread.Run(func() error {
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.DisableVertexAttribArray(uint32(l))
|
||||
gl.DisableVertexAttribArray(uint32(index))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -293,7 +293,7 @@ func (c *context) deleteShader(s shader) {
|
||||
gl.Call("deleteShader", js.Value(s))
|
||||
}
|
||||
|
||||
func (c *context) newProgram(shaders []shader) (program, error) {
|
||||
func (c *context) newProgram(shaders []shader, attributes []string) (program, error) {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
v := gl.Call("createProgram")
|
||||
@ -304,6 +304,11 @@ func (c *context) newProgram(shaders []shader) (program, error) {
|
||||
for _, shader := range shaders {
|
||||
gl.Call("attachShader", v, js.Value(shader))
|
||||
}
|
||||
|
||||
for i, name := range attributes {
|
||||
gl.Call("bindAttribLocation", v, i, name)
|
||||
}
|
||||
|
||||
gl.Call("linkProgram", v)
|
||||
if !gl.Call("getProgramParameter", v, linkStatus).Bool() {
|
||||
return program{}, errors.New("opengl: program error")
|
||||
@ -374,31 +379,22 @@ func (c *context) uniformFloats(p program, location string, v []float32) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) getAttribLocationImpl(p program, location string) attribLocation {
|
||||
func (c *context) vertexAttribPointer(p program, index int, size int, dataType dataType, stride int, offset int) {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
return attribLocation(gl.Call("getAttribLocation", p.value, location).Int())
|
||||
gl.Call("vertexAttribPointer", index, size, int(dataType), false, stride, offset)
|
||||
}
|
||||
|
||||
func (c *context) vertexAttribPointer(p program, location string, size int, dataType dataType, stride int, offset int) {
|
||||
func (c *context) enableVertexAttribArray(p program, index int) {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.Call("vertexAttribPointer", int(l), size, int(dataType), false, stride, offset)
|
||||
gl.Call("enableVertexAttribArray", index)
|
||||
}
|
||||
|
||||
func (c *context) enableVertexAttribArray(p program, location string) {
|
||||
func (c *context) disableVertexAttribArray(p program, index int) {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.Call("enableVertexAttribArray", int(l))
|
||||
}
|
||||
|
||||
func (c *context) disableVertexAttribArray(p program, location string) {
|
||||
c.ensureGL()
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.Call("disableVertexAttribArray", int(l))
|
||||
gl.Call("disableVertexAttribArray", index)
|
||||
}
|
||||
|
||||
func (c *context) newArrayBuffer(size int) buffer {
|
||||
|
@ -243,7 +243,7 @@ func (c *context) deleteShader(s shader) {
|
||||
gl.DeleteShader(mgl.Shader(s))
|
||||
}
|
||||
|
||||
func (c *context) newProgram(shaders []shader) (program, error) {
|
||||
func (c *context) newProgram(shaders []shader, attributes []string) (program, error) {
|
||||
gl := c.gl
|
||||
p := gl.CreateProgram()
|
||||
if p.Value == 0 {
|
||||
@ -253,6 +253,11 @@ func (c *context) newProgram(shaders []shader) (program, error) {
|
||||
for _, shader := range shaders {
|
||||
gl.AttachShader(p, mgl.Shader(shader))
|
||||
}
|
||||
|
||||
for i, name := range attributes {
|
||||
gl.BindAttribLocation(p, mgl.Attrib{uint(i)}, name)
|
||||
}
|
||||
|
||||
gl.LinkProgram(p)
|
||||
v := gl.GetProgrami(p, mgl.LINK_STATUS)
|
||||
if v == mgl.FALSE {
|
||||
@ -308,31 +313,19 @@ func (c *context) uniformFloats(p program, location string, v []float32) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) getAttribLocationImpl(p program, location string) attribLocation {
|
||||
func (c *context) vertexAttribPointer(p program, index int, size int, dataType dataType, stride int, offset int) {
|
||||
gl := c.gl
|
||||
a := attribLocation(gl.GetAttribLocation(mgl.Program(p), location))
|
||||
if a.Value == ^uint(0) {
|
||||
panic("invalid attrib location: " + location)
|
||||
}
|
||||
return a
|
||||
gl.VertexAttribPointer(mgl.Attrib{uint(index)}, size, mgl.Enum(dataType), false, stride, offset)
|
||||
}
|
||||
|
||||
func (c *context) vertexAttribPointer(p program, location string, size int, dataType dataType, stride int, offset int) {
|
||||
func (c *context) enableVertexAttribArray(p program, index int) {
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.VertexAttribPointer(mgl.Attrib(l), size, mgl.Enum(dataType), false, stride, offset)
|
||||
gl.EnableVertexAttribArray(mgl.Attrib{uint(index)})
|
||||
}
|
||||
|
||||
func (c *context) enableVertexAttribArray(p program, location string) {
|
||||
func (c *context) disableVertexAttribArray(p program, index int) {
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.EnableVertexAttribArray(mgl.Attrib(l))
|
||||
}
|
||||
|
||||
func (c *context) disableVertexAttribArray(p program, location string) {
|
||||
gl := c.gl
|
||||
l := c.locationCache.GetAttribLocation(c, p, location)
|
||||
gl.DisableVertexAttribArray(mgl.Attrib(l))
|
||||
gl.DisableVertexAttribArray(mgl.Attrib{uint(index)})
|
||||
}
|
||||
|
||||
func (c *context) newArrayBuffer(size int) buffer {
|
||||
|
@ -18,13 +18,11 @@ package opengl
|
||||
|
||||
type locationCache struct {
|
||||
uniformLocationCache map[programID]map[string]uniformLocation
|
||||
attribLocationCache map[programID]map[string]attribLocation
|
||||
}
|
||||
|
||||
func newLocationCache() *locationCache {
|
||||
return &locationCache{
|
||||
uniformLocationCache: map[programID]map[string]uniformLocation{},
|
||||
attribLocationCache: map[programID]map[string]attribLocation{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,16 +38,3 @@ func (c *locationCache) GetUniformLocation(context *context, p program, location
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (c *locationCache) GetAttribLocation(context *context, p program, location string) attribLocation {
|
||||
id := getProgramID(p)
|
||||
if _, ok := c.attribLocationCache[id]; !ok {
|
||||
c.attribLocationCache[id] = map[string]attribLocation{}
|
||||
}
|
||||
l, ok := c.attribLocationCache[id][location]
|
||||
if !ok {
|
||||
l = context.getAttribLocationImpl(p, location)
|
||||
c.attribLocationCache[id][location] = l
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
@ -38,6 +38,14 @@ type arrayBufferLayout struct {
|
||||
total int
|
||||
}
|
||||
|
||||
func (a *arrayBufferLayout) names() []string {
|
||||
ns := make([]string, len(a.parts))
|
||||
for i, p := range a.parts {
|
||||
ns[i] = p.name
|
||||
}
|
||||
return ns
|
||||
}
|
||||
|
||||
// totalBytes returns the size in bytes for one element of the array buffer.
|
||||
func (a *arrayBufferLayout) totalBytes() int {
|
||||
if a.total != 0 {
|
||||
@ -58,13 +66,13 @@ func (a *arrayBufferLayout) newArrayBuffer(context *context) buffer {
|
||||
|
||||
// enable binds the array buffer the given program to use the array buffer.
|
||||
func (a *arrayBufferLayout) enable(context *context, program program) {
|
||||
for _, p := range a.parts {
|
||||
context.enableVertexAttribArray(program, p.name)
|
||||
for i := range a.parts {
|
||||
context.enableVertexAttribArray(program, i)
|
||||
}
|
||||
total := a.totalBytes()
|
||||
offset := 0
|
||||
for _, p := range a.parts {
|
||||
context.vertexAttribPointer(program, p.name, p.num, float, total, offset)
|
||||
for i, p := range a.parts {
|
||||
context.vertexAttribPointer(program, i, p.num, float, total, offset)
|
||||
offset += float.SizeInBytes() * p.num
|
||||
}
|
||||
}
|
||||
@ -72,8 +80,8 @@ func (a *arrayBufferLayout) enable(context *context, program program) {
|
||||
// disable stops using the array buffer.
|
||||
func (a *arrayBufferLayout) disable(context *context, program program) {
|
||||
// TODO: Disabling should be done in reversed order?
|
||||
for _, p := range a.parts {
|
||||
context.disableVertexAttribArray(program, p.name)
|
||||
for i := range a.parts {
|
||||
context.disableVertexAttribArray(program, i)
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,10 +218,12 @@ func (s *openGLState) reset(context *context) error {
|
||||
program, err := context.newProgram([]shader{
|
||||
shaderVertexModelviewNative,
|
||||
shaderFragmentColorMatrixNative,
|
||||
})
|
||||
}, theArrayBufferLayout.names())
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.programs[programKey{
|
||||
filter: f,
|
||||
address: a,
|
||||
|
@ -234,9 +234,6 @@ void main(void) {
|
||||
highp vec2 p0 = pos - texel_size / 2.0 / scale;
|
||||
highp vec2 p1 = pos + texel_size / 2.0 / scale;
|
||||
|
||||
// Prevent this variable from being optimized out.
|
||||
p0 += varying_tex_region.xy - varying_tex_region.xy;
|
||||
|
||||
p1 = adjustTexel(p0, p1);
|
||||
|
||||
vec4 c0 = texture2D(texture, p0);
|
||||
|
Loading…
Reference in New Issue
Block a user