// SetUniform sets a uniform variable using the appropriate glUniform* or glUniformMatrix* call. It supports arrays of float32 and float64 or Mat4 objects. // NB: The underlying API does not support double precision, being able to pass float64 values is for convenience only. // BUG: It does not support non-square matrices. func (p *Program) SetUniform(loc string, data interface{}) { uni := p.uni[loc] switch f := data.(type) { case float32: C.glUniform1f(uni, C.GLfloat(f)) case [1]float32: C.glUniform1f(uni, C.GLfloat(f[0])) case [2]float32: C.glUniform2f(uni, C.GLfloat(f[0]), C.GLfloat(f[1])) case [3]float32: C.glUniform3f(uni, C.GLfloat(f[0]), C.GLfloat(f[1]), C.GLfloat(f[2])) case [4]float32: C.glUniform4f(uni, C.GLfloat(f[0]), C.GLfloat(f[1]), C.GLfloat(f[2]), C.GLfloat(f[3])) case float64: C.glUniform1f(uni, C.GLfloat(f)) case [1]float64: C.glUniform1f(uni, C.GLfloat(f[0])) case [2]float64: C.glUniform2f(uni, C.GLfloat(f[0]), C.GLfloat(f[1])) case [3]float64: C.glUniform3f(uni, C.GLfloat(f[0]), C.GLfloat(f[1]), C.GLfloat(f[2])) case [4]float64: C.glUniform4f(uni, C.GLfloat(f[0]), C.GLfloat(f[1]), C.GLfloat(f[2]), C.GLfloat(f[3])) case int: C.glUniform1i(uni, C.GLint(f)) case [1]int: C.glUniform1i(uni, C.GLint(f[0])) case [2]int: C.glUniform2i(uni, C.GLint(f[0]), C.GLint(f[1])) case [3]int: C.glUniform3i(uni, C.GLint(f[0]), C.GLint(f[1]), C.GLint(f[2])) case [4]int: C.glUniform4i(uni, C.GLint(f[0]), C.GLint(f[1]), C.GLint(f[2]), C.GLint(f[3])) case [2][2]float32: g := [4]C.GLfloat{C.GLfloat(f[0][0]), C.GLfloat(f[1][0]), C.GLfloat(f[0][1]), C.GLfloat(f[1][1])} C.glUniformMatrix2fv(uni, 1, FALSE, &g[0]) case [2][2]float64: g := [4]C.GLfloat{C.GLfloat(f[0][0]), C.GLfloat(f[1][0]), C.GLfloat(f[0][1]), C.GLfloat(f[1][1])} C.glUniformMatrix2fv(uni, 1, FALSE, &g[0]) case [3][3]float32: g := [9]C.GLfloat{C.GLfloat(f[0][0]), C.GLfloat(f[1][0]), C.GLfloat(f[2][0]), C.GLfloat(f[0][1]), C.GLfloat(f[1][1]), C.GLfloat(f[2][1]), C.GLfloat(f[0][2]), C.GLfloat(f[1][2]), C.GLfloat(f[2][2])} C.glUniformMatrix3fv(uni, 1, FALSE, &g[0]) case [3][3]float64: g := [9]C.GLfloat{C.GLfloat(f[0][0]), C.GLfloat(f[1][0]), C.GLfloat(f[2][0]), C.GLfloat(f[0][1]), C.GLfloat(f[1][1]), C.GLfloat(f[2][1]), C.GLfloat(f[0][2]), C.GLfloat(f[1][2]), C.GLfloat(f[2][2])} C.glUniformMatrix3fv(uni, 1, FALSE, &g[0]) case [4][4]float32: g := [16]C.GLfloat{C.GLfloat(f[0][0]), C.GLfloat(f[1][0]), C.GLfloat(f[2][0]), C.GLfloat(f[3][0]), C.GLfloat(f[0][1]), C.GLfloat(f[1][1]), C.GLfloat(f[2][1]), C.GLfloat(f[3][1]), C.GLfloat(f[0][2]), C.GLfloat(f[1][2]), C.GLfloat(f[2][2]), C.GLfloat(f[3][2]), C.GLfloat(f[0][3]), C.GLfloat(f[1][3]), C.GLfloat(f[2][3]), C.GLfloat(f[3][3])} C.glUniformMatrix4fv(uni, 1, FALSE, &g[0]) case [4][4]float64: g := [16]C.GLfloat{C.GLfloat(f[0][0]), C.GLfloat(f[1][0]), C.GLfloat(f[2][0]), C.GLfloat(f[3][0]), C.GLfloat(f[0][1]), C.GLfloat(f[1][1]), C.GLfloat(f[2][1]), C.GLfloat(f[3][1]), C.GLfloat(f[0][2]), C.GLfloat(f[1][2]), C.GLfloat(f[2][2]), C.GLfloat(f[3][2]), C.GLfloat(f[0][3]), C.GLfloat(f[1][3]), C.GLfloat(f[2][3]), C.GLfloat(f[3][3])} C.glUniformMatrix4fv(uni, 1, FALSE, &g[0]) case Mat4: g := [16]C.GLfloat{C.GLfloat(f[0][0]), C.GLfloat(f[1][0]), C.GLfloat(f[2][0]), C.GLfloat(f[3][0]), C.GLfloat(f[0][1]), C.GLfloat(f[1][1]), C.GLfloat(f[2][1]), C.GLfloat(f[3][1]), C.GLfloat(f[0][2]), C.GLfloat(f[1][2]), C.GLfloat(f[2][2]), C.GLfloat(f[3][2]), C.GLfloat(f[0][3]), C.GLfloat(f[1][3]), C.GLfloat(f[2][3]), C.GLfloat(f[3][3])} C.glUniformMatrix4fv(uni, 1, FALSE, &g[0]) default: panic("invalid type passed to SetUniform()") } }
func UniformMatrix2fv(dst Uniform, src []float32) { defer func() { errstr := errDrain() log.Printf("gl.UniformMatrix2fv(%v, len(%d)) %v", dst, len(src), errstr) }() C.glUniformMatrix2fv(dst.c(), C.GLsizei(len(src)/4), 0, (*C.GLfloat)(&src[0])) }
func UniformMatrix2fv( location int32, count Sizei, transpose bool, value *float32) { C.glUniformMatrix2fv( C.GLint(location), C.GLsizei(count), glBoolean(transpose), (*C.GLfloat)(value)) }
func (location UniformLocation) UniformMatrix2fv(transpose bool, list ...[]float32) { if len(list) < 1 { panic(ErrorInputSize) } // Maybe this isn't the best solution because of added overhead. for i, _ := range list { if len(list[i]) != 2 { panic(ErrorInputSize) } } C.glUniformMatrix2fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) }
func UniformMatrix2fv(dst Uniform, src []float32) { // OpenGL ES 2 does not support transpose. C.glUniformMatrix2fv(dst.c(), C.GLsizei(len(src)/4), 0, (*C.GLfloat)(&src[0])) }
func UniformMatrix2fv(location, count int, transpose bool, value []float32) { C.glUniformMatrix2fv(C.GLint(location), C.GLsizei(count), glBoolean(transpose), (*C.GLfloat)(&value[0])) }
func (location UniformLocation) UniformMatrix2f(transpose bool, matrix *[4]float32) { if matrix == nil { panic("Matrix is nil") } C.glUniformMatrix2fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) }
func (location UniformLocation) UniformMatrix2fv(transpose bool, list ...[4]float32) { if len(list) < 1 { panic("Invalid array length - must be at least 1") } C.glUniformMatrix2fv(C.GLint(location), C.GLsizei(len(list)), glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&list[0])))) }
func (location UniformLocation) UniformMatrix2f(transpose bool, matrix []float32) { if len(matrix) != 2 { panic(ErrorInputSize) } C.glUniformMatrix2fv(C.GLint(location), 1, glBool(transpose), ((*C.GLfloat)((unsafe.Pointer)(&matrix[0])))) }