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 return c
} }
// BindUniform will add a uniform with any supported underlying variable // SetUniform will update the named uniform with the value of any supported underlying
// if the uniform already exists, including defaults, they will be reassigned // attribute variable. If the uniform already exists, including defaults, they will be reassigned
// to the new value // to the new value. The value can be a pointer.
func (c *Canvas) BindUniform(Name string, Value interface{}) { func (c *Canvas) SetUniform(Name string, Value interface{}) {
c.shader.AddUniform(Name, Value) c.shader.AddUniform(Name, Value)
} }
// UpdateShader needs to be called after any changes to the underlying GLShader // 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() { func (c *Canvas) UpdateShader() {
c.shader.update() c.shader.update()
} }
// SetFragmentShader allows you to define a new fragment shader on the underlying // SetFragmentShader allows you to set a new fragment shader on the underlying
// GLShader. fs is the GLSL source, not a filename // framebuffer. Argument "fs" is the GLSL source, not a filename.
func (c *Canvas) SetFragmentShader(fs string) { func (c *Canvas) SetFragmentShader(fs string) {
c.shader.fs = fs c.shader.fs = fs
} }
@ -204,7 +204,7 @@ func (c *Canvas) setUniforms(texbounds pixel.Rect) {
} }
for loc, u := range c.shader.uniforms { 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 { 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 { if tex == nil {

View File

@ -10,28 +10,27 @@ import (
// GLShader is a type to assist with managing a canvas's underlying // GLShader is a type to assist with managing a canvas's underlying
// shader configuration. This allows for customization of shaders on // shader configuration. This allows for customization of shaders on
// a per canvas basis. // a per canvas basis.
type ( type GLShader struct {
GLShader struct { s *glhf.Shader
s *glhf.Shader vf, uf glhf.AttrFormat
vf, uf glhf.AttrFormat vs, fs string
vs, fs string
uniforms []gsUniformAttr uniforms []gsUniformAttr
uniformDefaults struct { uniformDefaults struct {
transform mgl32.Mat3 transform mgl32.Mat3
colormask mgl32.Vec4 colormask mgl32.Vec4
bounds mgl32.Vec4 bounds mgl32.Vec4
texbounds mgl32.Vec4 texbounds mgl32.Vec4
}
} }
}
gsUniformAttr struct { type gsUniformAttr struct {
Name string Name string
Type AttrType Type glhf.AttrType
Value interface{} value interface{}
} ispointer bool
) }
// reinitialize GLShader data and recompile the underlying gl shader object // reinitialize GLShader data and recompile the underlying gl shader object
func (gs *GLShader) update() { func (gs *GLShader) update() {
@ -39,7 +38,7 @@ func (gs *GLShader) update() {
for _, u := range gs.uniforms { for _, u := range gs.uniforms {
gs.uf = append(gs.uf, glhf.Attr{ gs.uf = append(gs.uf, glhf.Attr{
Name: u.Name, Name: u.Name,
Type: glhf.AttrType(u.Type), Type: u.Type,
}) })
} }
var shader *glhf.Shader var shader *glhf.Shader
@ -69,31 +68,33 @@ func (gs *GLShader) getUniform(Name string) int {
return -1 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)
// //
// utime := float32(time.Since(starttime)).Seconds())
// mycanvas.shader.AddUniform("u_time", &utime)
func (gs *GLShader) AddUniform(Name string, Value interface{}) { func (gs *GLShader) AddUniform(Name string, Value interface{}) {
Type := getAttrType(Value) t, p := getAttrType(Value)
if loc := gs.getUniform(Name); loc > -1 { if loc := gs.getUniform(Name); loc > -1 {
gs.uniforms[loc].Name = Name gs.uniforms[loc].Name = Name
gs.uniforms[loc].Type = Type gs.uniforms[loc].Type = t
gs.uniforms[loc].Value = Value gs.uniforms[loc].ispointer = p
gs.uniforms[loc].value = Value
return return
} }
gs.uniforms = append(gs.uniforms, gsUniformAttr{ gs.uniforms = append(gs.uniforms, gsUniformAttr{
Name: Name, Name: Name,
Type: Type, Type: t,
Value: Value, 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 // canvas to render correctly. The defaults can be overridden
// by simply using AddUniform() // by simply using the AddUniform function.
func baseShader(c *Canvas) { func baseShader(c *Canvas) {
gs := &GLShader{ gs := &GLShader{
vf: defaultCanvasVertexFormat, vf: defaultCanvasVertexFormat,
@ -109,6 +110,111 @@ func baseShader(c *Canvas) {
c.shader = gs 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 = ` var defaultCanvasVertexShader = `
#version 330 core #version 330 core

View File

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