image: Introduce programContext (#144)

This commit is contained in:
Hajime Hoshi 2016-02-07 05:13:54 +09:00
parent eb9379c3a6
commit c54b5c4b06
2 changed files with 46 additions and 35 deletions

View File

@ -55,8 +55,16 @@ func drawTexture(c *opengl.Context, texture opengl.Texture, projectionMatrix *[4
return errors.New(fmt.Sprintf("len(quads) must be equal to or less than %d", quadsMaxNum)) return errors.New(fmt.Sprintf("len(quads) must be equal to or less than %d", quadsMaxNum))
} }
f := useProgramForTexture(c, glMatrix(projectionMatrix), texture, geo, color) p := programContext{
defer f.FinishProgram() program: programTexture,
context: c,
projectionMatrix: glMatrix(projectionMatrix),
texture: texture,
geoM: geo,
colorM: color,
}
p.begin()
defer p.end()
vertices := vertices[0:0] vertices := vertices[0:0]
num := 0 num := 0

View File

@ -99,38 +99,40 @@ var (
lastColorMatrix []float32 lastColorMatrix []float32
) )
type programFinisher func() type programContext struct {
program opengl.Program
func (p programFinisher) FinishProgram() { context *opengl.Context
p() projectionMatrix []float32
texture opengl.Texture
geoM Matrix
colorM Matrix
} }
func useProgramForTexture(c *opengl.Context, projectionMatrix []float32, texture opengl.Texture, geo Matrix, color Matrix) programFinisher { func (p *programContext) begin() {
if !lastProgram.Equals(programTexture) { c := p.context
c.UseProgram(programTexture) if !lastProgram.Equals(p.program) {
c.UseProgram(p.program)
lastProgram = programTexture lastProgram = programTexture
lastProjectionMatrix = nil lastProjectionMatrix = nil
lastModelviewMatrix = nil lastModelviewMatrix = nil
lastColorMatrix = nil lastColorMatrix = nil
} }
program := programTexture
c.BindElementArrayBuffer(indexBufferQuads) c.BindElementArrayBuffer(indexBufferQuads)
if !areSameFloat32Array(lastProjectionMatrix, projectionMatrix) { if !areSameFloat32Array(lastProjectionMatrix, p.projectionMatrix) {
c.UniformFloats(program, "projection_matrix", projectionMatrix) c.UniformFloats(p.program, "projection_matrix", p.projectionMatrix)
if lastProjectionMatrix == nil { if lastProjectionMatrix == nil {
lastProjectionMatrix = make([]float32, 16) lastProjectionMatrix = make([]float32, 16)
} }
copy(lastProjectionMatrix, projectionMatrix) copy(lastProjectionMatrix, p.projectionMatrix)
} }
ma := float32(geo.Element(0, 0)) ma := float32(p.geoM.Element(0, 0))
mb := float32(geo.Element(0, 1)) mb := float32(p.geoM.Element(0, 1))
mc := float32(geo.Element(1, 0)) mc := float32(p.geoM.Element(1, 0))
md := float32(geo.Element(1, 1)) md := float32(p.geoM.Element(1, 1))
tx := float32(geo.Element(0, 2)) tx := float32(p.geoM.Element(0, 2))
ty := float32(geo.Element(1, 2)) ty := float32(p.geoM.Element(1, 2))
modelviewMatrix := []float32{ modelviewMatrix := []float32{
ma, mc, 0, 0, ma, mc, 0, 0,
mb, md, 0, 0, mb, md, 0, 0,
@ -138,19 +140,19 @@ func useProgramForTexture(c *opengl.Context, projectionMatrix []float32, texture
tx, ty, 0, 1, tx, ty, 0, 1,
} }
if !areSameFloat32Array(lastModelviewMatrix, modelviewMatrix) { if !areSameFloat32Array(lastModelviewMatrix, modelviewMatrix) {
c.UniformFloats(program, "modelview_matrix", modelviewMatrix) c.UniformFloats(p.program, "modelview_matrix", modelviewMatrix)
if lastModelviewMatrix == nil { if lastModelviewMatrix == nil {
lastModelviewMatrix = make([]float32, 16) lastModelviewMatrix = make([]float32, 16)
} }
copy(lastModelviewMatrix, modelviewMatrix) copy(lastModelviewMatrix, modelviewMatrix)
} }
c.UniformInt(program, "texture", 0) c.UniformInt(p.program, "texture", 0)
e := [4][5]float32{} e := [4][5]float32{}
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ { for j := 0; j < 5; j++ {
e[i][j] = float32(color.Element(i, j)) e[i][j] = float32(p.colorM.Element(i, j))
} }
} }
@ -161,7 +163,7 @@ func useProgramForTexture(c *opengl.Context, projectionMatrix []float32, texture
e[0][3], e[1][3], e[2][3], e[3][3], e[0][3], e[1][3], e[2][3], e[3][3],
} }
if !areSameFloat32Array(lastColorMatrix, colorMatrix) { if !areSameFloat32Array(lastColorMatrix, colorMatrix) {
c.UniformFloats(program, "color_matrix", colorMatrix) c.UniformFloats(p.program, "color_matrix", colorMatrix)
if lastColorMatrix == nil { if lastColorMatrix == nil {
lastColorMatrix = make([]float32, 16) lastColorMatrix = make([]float32, 16)
} }
@ -170,20 +172,21 @@ func useProgramForTexture(c *opengl.Context, projectionMatrix []float32, texture
colorMatrixTranslation := []float32{ colorMatrixTranslation := []float32{
e[0][4], e[1][4], e[2][4], e[3][4], e[0][4], e[1][4], e[2][4], e[3][4],
} }
c.UniformFloats(program, "color_matrix_translation", colorMatrixTranslation) c.UniformFloats(p.program, "color_matrix_translation", colorMatrixTranslation)
// 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
c.BindTexture(texture) c.BindTexture(p.texture)
c.EnableVertexAttribArray(program, "vertex") c.EnableVertexAttribArray(p.program, "vertex")
c.EnableVertexAttribArray(program, "tex_coord") c.EnableVertexAttribArray(p.program, "tex_coord")
c.VertexAttribPointer(program, "vertex", true, false, int16Size*4, 2, int16Size*0) c.VertexAttribPointer(p.program, "vertex", true, false, int16Size*4, 2, int16Size*0)
c.VertexAttribPointer(program, "tex_coord", true, true, int16Size*4, 2, int16Size*2) c.VertexAttribPointer(p.program, "tex_coord", true, true, int16Size*4, 2, int16Size*2)
}
return func() {
c.DisableVertexAttribArray(program, "tex_coord") func (p *programContext) end() {
c.DisableVertexAttribArray(program, "vertex") c := p.context
} c.DisableVertexAttribArray(p.program, "tex_coord")
c.DisableVertexAttribArray(p.program, "vertex")
} }