2013-10-30 14:26:10 +01:00
|
|
|
package shader
|
|
|
|
|
|
|
|
import (
|
2014-12-06 07:47:48 +01:00
|
|
|
"github.com/go-gl/gl"
|
2014-12-09 14:09:22 +01:00
|
|
|
"github.com/hajimehoshi/ebiten"
|
2013-12-13 21:34:27 +01:00
|
|
|
"sync"
|
2013-10-30 14:26:10 +01:00
|
|
|
)
|
|
|
|
|
2014-12-09 14:09:22 +01:00
|
|
|
func glMatrix(ebiten [4][4]float64) [16]float32 {
|
2014-12-07 10:25:28 +01:00
|
|
|
result := [16]float32{}
|
|
|
|
for j := 0; j < 4; j++ {
|
|
|
|
for i := 0; i < 4; i++ {
|
2014-12-09 14:09:22 +01:00
|
|
|
result[i+j*4] = float32(ebiten[i][j])
|
2014-12-07 10:25:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2013-12-13 21:34:27 +01:00
|
|
|
var once sync.Once
|
|
|
|
|
2014-12-09 14:09:22 +01:00
|
|
|
// TODO: Use VBO
|
|
|
|
func DrawTexture(native gl.Texture, width, height int, projectionMatrix [4][4]float64, parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) {
|
2013-12-13 21:34:27 +01:00
|
|
|
once.Do(func() {
|
2013-10-30 14:26:10 +01:00
|
|
|
initialize()
|
2013-12-13 21:34:27 +01:00
|
|
|
})
|
2013-10-30 14:26:10 +01:00
|
|
|
|
2014-12-07 20:22:50 +01:00
|
|
|
if len(parts) == 0 {
|
2013-10-30 14:26:10 +01:00
|
|
|
return
|
|
|
|
}
|
2014-12-07 20:22:50 +01:00
|
|
|
quads := textureQuads(parts, width, height)
|
2014-05-03 20:29:45 +02:00
|
|
|
// TODO: Check performance
|
2014-12-07 10:25:28 +01:00
|
|
|
shaderProgram := use(glMatrix(projectionMatrix), geo, color)
|
2013-11-25 17:08:12 +01:00
|
|
|
|
2014-12-06 07:47:48 +01:00
|
|
|
native.Bind(gl.TEXTURE_2D)
|
|
|
|
defer gl.Texture(0).Bind(gl.TEXTURE_2D)
|
2013-10-30 14:26:10 +01:00
|
|
|
|
|
|
|
vertexAttrLocation := getAttributeLocation(shaderProgram, "vertex")
|
2013-12-13 21:34:27 +01:00
|
|
|
texCoordAttrLocation := getAttributeLocation(shaderProgram, "tex_coord")
|
2013-10-30 14:26:10 +01:00
|
|
|
|
2014-12-06 07:47:48 +01:00
|
|
|
gl.EnableClientState(gl.VERTEX_ARRAY)
|
|
|
|
gl.EnableClientState(gl.TEXTURE_COORD_ARRAY)
|
|
|
|
vertexAttrLocation.EnableArray()
|
|
|
|
texCoordAttrLocation.EnableArray()
|
2013-10-30 14:26:10 +01:00
|
|
|
defer func() {
|
2014-12-06 07:47:48 +01:00
|
|
|
texCoordAttrLocation.DisableArray()
|
|
|
|
vertexAttrLocation.DisableArray()
|
|
|
|
gl.DisableClientState(gl.TEXTURE_COORD_ARRAY)
|
|
|
|
gl.DisableClientState(gl.VERTEX_ARRAY)
|
2013-10-30 14:26:10 +01:00
|
|
|
}()
|
|
|
|
|
|
|
|
vertices := []float32{}
|
|
|
|
texCoords := []float32{}
|
|
|
|
indicies := []uint32{}
|
2014-12-09 14:09:22 +01:00
|
|
|
// TODO: Check len(parts) and gl.MAX_ELEMENTS_INDICES?
|
2013-10-30 14:26:10 +01:00
|
|
|
for i, quad := range quads {
|
|
|
|
x1 := quad.VertexX1
|
|
|
|
x2 := quad.VertexX2
|
|
|
|
y1 := quad.VertexY1
|
|
|
|
y2 := quad.VertexY2
|
|
|
|
vertices = append(vertices,
|
|
|
|
x1, y1,
|
|
|
|
x2, y1,
|
|
|
|
x1, y2,
|
|
|
|
x2, y2,
|
|
|
|
)
|
|
|
|
u1 := quad.TextureCoordU1
|
|
|
|
u2 := quad.TextureCoordU2
|
|
|
|
v1 := quad.TextureCoordV1
|
|
|
|
v2 := quad.TextureCoordV2
|
|
|
|
texCoords = append(texCoords,
|
|
|
|
u1, v1,
|
|
|
|
u2, v1,
|
|
|
|
u1, v2,
|
|
|
|
u2, v2,
|
|
|
|
)
|
|
|
|
base := uint32(i * 4)
|
|
|
|
indicies = append(indicies,
|
|
|
|
base, base+1, base+2,
|
|
|
|
base+1, base+2, base+3,
|
|
|
|
)
|
|
|
|
}
|
2014-12-06 07:47:48 +01:00
|
|
|
vertexAttrLocation.AttribPointer(2, gl.FLOAT, false, 0, vertices)
|
|
|
|
texCoordAttrLocation.AttribPointer(2, gl.FLOAT, false, 0, texCoords)
|
|
|
|
gl.DrawElements(gl.TRIANGLES, len(indicies), gl.UNSIGNED_INT, indicies)
|
2013-10-30 14:26:10 +01:00
|
|
|
}
|