This commit is contained in:
Brandon 2018-10-03 13:02:10 -06:00
parent 45642083a2
commit a25a444cbf
4 changed files with 149 additions and 145 deletions

View File

@ -1,102 +0,0 @@
package pixelgl
import "github.com/go-gl/mathgl/mgl32"
// AttrType is the attribute's identifier
type AttrType int
// List of all possible attribute types.
const (
Int AttrType = iota
Float
Vec2
Vec3
Vec4
Mat2
Mat23
Mat24
Mat3
Mat32
Mat34
Mat4
Mat42
Mat43
Intp // pointers
Floatp
Vec2p
Vec3p
Vec4p
Mat2p
Mat23p
Mat24p
Mat3p
Mat32p
Mat34p
Mat4p
Mat42p
Mat43p
)
// Returns the type identifier for any (supported) variable type
func getAttrType(v interface{}) AttrType {
switch v.(type) {
case int32:
return Int
case float32:
return Float
case mgl32.Vec2:
return Vec2
case mgl32.Vec3:
return Vec3
case mgl32.Vec4:
return Vec4
case mgl32.Mat2:
return Mat2
case mgl32.Mat2x3:
return Mat23
case mgl32.Mat2x4:
return Mat24
case mgl32.Mat3:
return Mat3
case mgl32.Mat3x2:
return Mat32
case mgl32.Mat3x4:
return Mat34
case mgl32.Mat4:
return Mat4
case mgl32.Mat4x2:
return Mat42
case mgl32.Mat4x3:
return Mat43
case *mgl32.Vec2:
return Vec2p
case *mgl32.Vec3:
return Vec3p
case *mgl32.Vec4:
return Vec4p
case *mgl32.Mat2:
return Mat2p
case *mgl32.Mat2x3:
return Mat23p
case *mgl32.Mat2x4:
return Mat24p
case *mgl32.Mat3:
return Mat3p
case *mgl32.Mat3x2:
return Mat32p
case *mgl32.Mat3x4:
return Mat34p
case *mgl32.Mat4:
return Mat4p
case *mgl32.Mat4x2:
return Mat42p
case *mgl32.Mat4x3:
return Mat43p
case *int32:
return Intp
case *float32:
return Floatp
default:
panic("invalid AttrType")
}
}

View File

@ -43,21 +43,21 @@ func NewCanvas(bounds pixel.Rect) *Canvas {
return c
}
// BindUniform will add a uniform with any supported underlying variable
// if the uniform already exists, including defaults, they will be reassigned
// to the new value
func (c *Canvas) BindUniform(Name string, Value interface{}) {
// SetUniform will update the named uniform with the value of any supported underlying
// attribute variable. If the uniform already exists, including defaults, they will be reassigned
// to the new value. The value can be a pointer.
func (c *Canvas) SetUniform(Name string, Value interface{}) {
c.shader.AddUniform(Name, Value)
}
// UpdateShader needs to be called after any changes to the underlying GLShader
// are made (ie, BindUniform(), SetFragmentShader()...)
// are made, such as, SetUniform, SetFragmentShader...
func (c *Canvas) UpdateShader() {
c.shader.update()
}
// SetFragmentShader allows you to define a new fragment shader on the underlying
// GLShader. fs is the GLSL source, not a filename
// SetFragmentShader allows you to set a new fragment shader on the underlying
// framebuffer. Argument "fs" is the GLSL source, not a filename.
func (c *Canvas) SetFragmentShader(fs string) {
c.shader.fs = fs
}
@ -204,7 +204,7 @@ func (c *Canvas) setUniforms(texbounds pixel.Rect) {
}
for loc, u := range c.shader.uniforms {
c.shader.s.SetUniformAttr(loc, u.Value)
c.shader.s.SetUniformAttr(loc, u.Value())
}
}
@ -336,7 +336,7 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, bounds pixel.Rect) {
}
for loc, u := range ct.dst.shader.uniforms {
ct.dst.shader.s.SetUniformAttr(loc, u.Value)
ct.dst.shader.s.SetUniformAttr(loc, u.Value())
}
if tex == nil {

View File

@ -10,8 +10,7 @@ import (
// GLShader is a type to assist with managing a canvas's underlying
// shader configuration. This allows for customization of shaders on
// a per canvas basis.
type (
GLShader struct {
type GLShader struct {
s *glhf.Shader
vf, uf glhf.AttrFormat
vs, fs string
@ -24,14 +23,14 @@ type (
bounds mgl32.Vec4
texbounds mgl32.Vec4
}
}
}
gsUniformAttr struct {
type gsUniformAttr struct {
Name string
Type AttrType
Value interface{}
}
)
Type glhf.AttrType
value interface{}
ispointer bool
}
// reinitialize GLShader data and recompile the underlying gl shader object
func (gs *GLShader) update() {
@ -39,7 +38,7 @@ func (gs *GLShader) update() {
for _, u := range gs.uniforms {
gs.uf = append(gs.uf, glhf.Attr{
Name: u.Name,
Type: glhf.AttrType(u.Type),
Type: u.Type,
})
}
var shader *glhf.Shader
@ -69,31 +68,33 @@ func (gs *GLShader) getUniform(Name string) int {
return -1
}
// AddUniform appends a custom uniform name and value to the shader
// AddUniform appends a custom uniform name and value to the shader.
// if the uniform already exists, it will simply be overwritten.
//
// To add a time uniform for example:
// example:
//
// utime := float32(time.Since(starttime)).Seconds())
// mycanvas.shader.AddUniform("u_time", &utime)
//
func (gs *GLShader) AddUniform(Name string, Value interface{}) {
Type := getAttrType(Value)
t, p := getAttrType(Value)
if loc := gs.getUniform(Name); loc > -1 {
gs.uniforms[loc].Name = Name
gs.uniforms[loc].Type = Type
gs.uniforms[loc].Value = Value
gs.uniforms[loc].Type = t
gs.uniforms[loc].ispointer = p
gs.uniforms[loc].value = Value
return
}
gs.uniforms = append(gs.uniforms, gsUniformAttr{
Name: Name,
Type: Type,
Value: Value,
Type: t,
ispointer: p,
value: Value,
})
}
// Sets up a base shader with everything needed for a pixel
// Sets up a base shader with everything needed for a Pixel
// canvas to render correctly. The defaults can be overridden
// by simply using AddUniform()
// by simply using the AddUniform function.
func baseShader(c *Canvas) {
gs := &GLShader{
vf: defaultCanvasVertexFormat,
@ -109,6 +110,111 @@ func baseShader(c *Canvas) {
c.shader = gs
}
// Value returns the attribute's concrete value. If the stored value
// is a pointer, we return the dereferenced value.
func (gu *gsUniformAttr) Value() interface{} {
if !gu.ispointer {
return gu.value
}
switch gu.Type {
case glhf.Vec2:
return *gu.value.(*mgl32.Vec2)
case glhf.Vec3:
return *gu.value.(*mgl32.Vec3)
case glhf.Vec4:
return *gu.value.(*mgl32.Vec4)
case glhf.Mat2:
return *gu.value.(*mgl32.Mat2)
case glhf.Mat23:
return *gu.value.(*mgl32.Mat2x3)
case glhf.Mat24:
return *gu.value.(*mgl32.Mat2x4)
case glhf.Mat3:
return *gu.value.(*mgl32.Mat3)
case glhf.Mat32:
return *gu.value.(*mgl32.Mat3x2)
case glhf.Mat34:
return *gu.value.(*mgl32.Mat3x4)
case glhf.Mat4:
return *gu.value.(*mgl32.Mat4)
case glhf.Mat42:
return *gu.value.(*mgl32.Mat4x2)
case glhf.Mat43:
return *gu.value.(*mgl32.Mat4x3)
case glhf.Int:
return *gu.value.(*int32)
case glhf.Float:
return *gu.value.(*float32)
default:
panic("invalid attrtype")
}
}
// Returns the type identifier for any (supported) attribute variable type
// and whether or not it is a pointer of that type.
func getAttrType(v interface{}) (glhf.AttrType, bool) {
switch v.(type) {
case int32:
return glhf.Int, false
case float32:
return glhf.Float, false
case mgl32.Vec2:
return glhf.Vec2, false
case mgl32.Vec3:
return glhf.Vec3, false
case mgl32.Vec4:
return glhf.Vec4, false
case mgl32.Mat2:
return glhf.Mat2, false
case mgl32.Mat2x3:
return glhf.Mat23, false
case mgl32.Mat2x4:
return glhf.Mat24, false
case mgl32.Mat3:
return glhf.Mat3, false
case mgl32.Mat3x2:
return glhf.Mat32, false
case mgl32.Mat3x4:
return glhf.Mat34, false
case mgl32.Mat4:
return glhf.Mat4, false
case mgl32.Mat4x2:
return glhf.Mat42, false
case mgl32.Mat4x3:
return glhf.Mat43, false
case *mgl32.Vec2:
return glhf.Vec2, true
case *mgl32.Vec3:
return glhf.Vec3, true
case *mgl32.Vec4:
return glhf.Vec4, true
case *mgl32.Mat2:
return glhf.Mat2, true
case *mgl32.Mat2x3:
return glhf.Mat23, true
case *mgl32.Mat2x4:
return glhf.Mat24, true
case *mgl32.Mat3:
return glhf.Mat3, true
case *mgl32.Mat3x2:
return glhf.Mat32, true
case *mgl32.Mat3x4:
return glhf.Mat34, true
case *mgl32.Mat4:
return glhf.Mat4, true
case *mgl32.Mat4x2:
return glhf.Mat42, true
case *mgl32.Mat4x3:
return glhf.Mat43, true
case *int32:
return glhf.Int, true
case *float32:
return glhf.Float, true
default:
panic("invalid AttrType")
}
}
var defaultCanvasVertexShader = `
#version 330 core

View File

@ -425,7 +425,7 @@ func (w *Window) Color(at pixel.Vec) pixel.RGBA {
return w.canvas.Color(at)
}
// GetCanvas returns the window's underlying Canvas
func (w *Window) GetCanvas() *Canvas {
// Canvas returns the window's underlying Canvas
func (w *Window) Canvas() *Canvas {
return w.canvas
}