ebiten/graphics/opengl/internal/shader/program.go
Hajime Hoshi 7d4540d863 gofmt
2014-12-06 22:56:57 +09:00

133 lines
3.3 KiB
Go

package shader
import (
"github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/graphics/matrix"
)
type program struct {
native gl.Program
shaderIds []shaderId
}
var programColorMatrix = program{
shaderIds: []shaderId{shaderVertex, shaderColorMatrix},
}
func (p *program) create() {
p.native = gl.CreateProgram()
if p.native == 0 {
panic("glCreateProgram failed")
}
for _, shaderId := range p.shaderIds {
p.native.AttachShader(shaders[shaderId].native)
}
p.native.Link()
if p.native.Get(gl.LINK_STATUS) == gl.FALSE {
panic("program error")
}
}
func initialize() {
for _, shader := range shaders {
shader.compile()
}
defer func() {
for _, shader := range shaders {
shader.delete()
}
}()
programColorMatrix.create()
programColorMatrix.native.Use()
}
type qualifierVariableType int
const (
qualifierVariableTypeAttribute qualifierVariableType = iota
qualifierVariableTypeUniform
)
var (
shaderLocationCache = map[qualifierVariableType]map[string]gl.AttribLocation{
qualifierVariableTypeAttribute: {},
qualifierVariableTypeUniform: {},
}
)
func getLocation(program gl.Program, name string, qvType qualifierVariableType) gl.AttribLocation {
if location, ok := shaderLocationCache[qvType][name]; ok {
return location
}
location := gl.AttribLocation(-1)
switch qvType {
case qualifierVariableTypeAttribute:
location = program.GetAttribLocation(name)
case qualifierVariableTypeUniform:
location = gl.AttribLocation(program.GetUniformLocation(name))
default:
panic("no reach")
}
if location == -1 {
panic("GetAttribLocation failed")
}
shaderLocationCache[qvType][name] = location
return location
}
func getAttributeLocation(program gl.Program, name string) gl.AttribLocation {
return getLocation(program, name, qualifierVariableTypeAttribute)
}
func getUniformLocation(program gl.Program, name string) gl.UniformLocation {
return gl.UniformLocation(getLocation(program, name, qualifierVariableTypeUniform))
}
func use(projectionMatrix [16]float32, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) gl.Program {
// TODO: Check the performance.
program := programColorMatrix
getUniformLocation(program.native, "projection_matrix").UniformMatrix4fv(false, projectionMatrix)
a := float32(geometryMatrix.Elements[0][0])
b := float32(geometryMatrix.Elements[0][1])
c := float32(geometryMatrix.Elements[1][0])
d := float32(geometryMatrix.Elements[1][1])
tx := float32(geometryMatrix.Elements[0][2])
ty := float32(geometryMatrix.Elements[1][2])
glModelviewMatrix := [...]float32{
a, c, 0, 0,
b, d, 0, 0,
0, 0, 1, 0,
tx, ty, 0, 1,
}
getUniformLocation(program.native, "modelview_matrix").UniformMatrix4fv(false, glModelviewMatrix)
getUniformLocation(program.native, "texture").Uniform1i(0)
e := [4][5]float32{}
for i := 0; i < 4; i++ {
for j := 0; j < 5; j++ {
e[i][j] = float32(colorMatrix.Elements[i][j])
}
}
glColorMatrix := [...]float32{
e[0][0], e[1][0], e[2][0], e[3][0],
e[0][1], e[1][1], e[2][1], e[3][1],
e[0][2], e[1][2], e[2][2], e[3][2],
e[0][3], e[1][3], e[2][3], e[3][3],
}
getUniformLocation(program.native, "color_matrix").UniformMatrix4fv(false, glColorMatrix)
glColorMatrixTranslation := [...]float32{
e[0][4], e[1][4], e[2][4], e[3][4],
}
getUniformLocation(program.native, "color_matrix_translation").Uniform4fv(1, glColorMatrixTranslation[:])
return program.native
}