Use location cache

This commit is contained in:
Hajime Hoshi 2015-01-12 23:16:34 +09:00
parent 9418d4c577
commit f0519b8604
3 changed files with 87 additions and 36 deletions

View File

@ -26,8 +26,14 @@ type Texture int
type Framebuffer int
type Shader int
type Program int
type UniformLocation int
type AttribLocation int
type UniformLocation gl.UniformLocation
type AttribLocation gl.AttribLocation
type ProgramID int
func GetProgramID(p Program) ProgramID {
return ProgramID(p)
}
type context struct{}
@ -173,13 +179,17 @@ func (c *Context) UseProgram(p Program) {
gl.Program(p).Use()
}
func (c *Context) GetUniformLocation(p Program, location string) UniformLocation {
return UniformLocation(gl.Program(p).GetUniformLocation(location))
}
func (c *Context) UniformInt(p Program, location string, v int) {
l := gl.Program(p).GetUniformLocation(location)
l := gl.UniformLocation(GetUniformLocation(c, p, location))
l.Uniform1i(v)
}
func (c *Context) UniformFloats(p Program, location string, v []float32) {
l := gl.Program(p).GetUniformLocation(location)
l := gl.UniformLocation(GetUniformLocation(c, p, location))
switch len(v) {
case 4:
l.Uniform4fv(1, v)
@ -192,16 +202,23 @@ func (c *Context) UniformFloats(p Program, location string, v []float32) {
}
}
func (c *Context) GetAttribLocation(p Program, location string) AttribLocation {
return AttribLocation(gl.Program(p).GetAttribLocation(location))
}
func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) {
gl.Program(p).GetAttribLocation(location).AttribPointer(2, gl.FLOAT, false, stride, v)
l := gl.AttribLocation(GetAttribLocation(c, p, location))
l.AttribPointer(2, gl.FLOAT, false, stride, v)
}
func (c *Context) EnableVertexAttribArray(p Program, location string) {
gl.Program(p).GetAttribLocation(location).EnableArray()
l := gl.AttribLocation(GetAttribLocation(c, p, location))
l.EnableArray()
}
func (c *Context) DisableVertexAttribArray(p Program, location string) {
gl.Program(p).GetAttribLocation(location).DisableArray()
l := gl.AttribLocation(GetAttribLocation(c, p, location))
l.DisableArray()
}
func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsageType BufferUsageType) {

View File

@ -30,6 +30,12 @@ type Program js.Object
type UniformLocation js.Object
type AttribLocation int
type ProgramID int
func GetProgramID(p Program) ProgramID {
return ProgramID(p.Get("__ebiten_programId").Int())
}
type context struct {
gl *webgl.Context
}
@ -175,12 +181,16 @@ func (c *Context) DeleteShader(s Shader) {
gl.DeleteShader(s)
}
var lastProgramID ProgramID = 0
func (c *Context) NewProgram(shaders []Shader) (Program, error) {
gl := c.gl
p := gl.CreateProgram()
if p == nil {
return nil, errors.New("glCreateProgram failed")
}
p.Set("__ebiten_programId", lastProgramID)
lastProgramID++
for _, shader := range shaders {
gl.AttachShader(p, shader)
@ -197,23 +207,20 @@ func (c *Context) UseProgram(p Program) {
gl.UseProgram(p)
}
func (c *Context) GetUniformLocation(p Program, location string) UniformLocation {
gl := c.gl
return gl.GetUniformLocation(p, location)
}
func (c *Context) UniformInt(p Program, location string, v int) {
gl := c.gl
l, ok := uniformLocationCache[location]
if !ok {
l = gl.GetUniformLocation(p, location)
uniformLocationCache[location] = l
}
l := GetUniformLocation(c, p, location)
gl.Uniform1i(l, v)
}
func (c *Context) UniformFloats(p Program, location string, v []float32) {
gl := c.gl
l, ok := uniformLocationCache[location]
if !ok {
l = gl.GetUniformLocation(p, location)
uniformLocationCache[location] = l
}
l := GetUniformLocation(c, p, location)
switch len(v) {
case 4:
gl.Call("uniform4fv", l, v)
@ -224,33 +231,26 @@ func (c *Context) UniformFloats(p Program, location string, v []float32) {
}
}
func (c *Context) GetAttribLocation(p Program, location string) AttribLocation {
gl := c.gl
return AttribLocation(gl.GetAttribLocation(p, location))
}
func (c *Context) VertexAttribPointer(p Program, location string, stride int, v uintptr) {
gl := c.gl
l, ok := attribLocationCache[location]
if !ok {
l = AttribLocation(gl.GetAttribLocation(p, location))
attribLocationCache[location] = l
}
l := GetAttribLocation(c, p, location)
gl.VertexAttribPointer(int(l), 2, gl.FLOAT, false, stride, int(v))
}
func (c *Context) EnableVertexAttribArray(p Program, location string) {
gl := c.gl
l, ok := attribLocationCache[location]
if !ok {
l = AttribLocation(gl.GetAttribLocation(p, location))
attribLocationCache[location] = l
}
l := GetAttribLocation(c, p, location)
gl.EnableVertexAttribArray(int(l))
}
func (c *Context) DisableVertexAttribArray(p Program, location string) {
gl := c.gl
l, ok := attribLocationCache[location]
if !ok {
l = AttribLocation(gl.GetAttribLocation(p, location))
attribLocationCache[location] = l
}
l := GetAttribLocation(c, p, location)
gl.DisableVertexAttribArray(int(l))
}

View File

@ -14,7 +14,41 @@
package opengl
// Note: This cache is created only for one program.
// If we use two or more programs, the key of the map should be changed.
var uniformLocationCache = map[string]UniformLocation{}
var attribLocationCache = map[string]AttribLocation{}
// Since js.Object (Program) can't be keys of a map, use integers (ProgramID) instead.
var uniformLocationCache = map[ProgramID]map[string]UniformLocation{}
var attribLocationCache = map[ProgramID]map[string]AttribLocation{}
type UniformLocationGetter interface {
GetUniformLocation(p Program, location string) UniformLocation
}
func GetUniformLocation(g UniformLocationGetter, p Program, location string) UniformLocation {
id := GetProgramID(p)
if _, ok := uniformLocationCache[id]; !ok {
uniformLocationCache[id] = map[string]UniformLocation{}
}
l, ok := uniformLocationCache[id][location]
if !ok {
l = g.GetUniformLocation(p, location)
uniformLocationCache[id][location] = l
}
return l
}
type AttribLocationGetter interface {
GetAttribLocation(p Program, location string) AttribLocation
}
func GetAttribLocation(g AttribLocationGetter, p Program, location string) AttribLocation {
id := GetProgramID(p)
if _, ok := attribLocationCache[id]; !ok {
attribLocationCache[id] = map[string]AttribLocation{}
}
l, ok := attribLocationCache[id][location]
if !ok {
l = g.GetAttribLocation(p, location)
attribLocationCache[id][location] = l
}
return l
}