Merge pull request #246 from dusk125/tri_shader
#244 GLTriangle's fragment shader is used when rendered by the Canvas.
This commit is contained in:
commit
6e34aae429
|
@ -19,7 +19,7 @@ import (
|
|||
// It supports TrianglesPosition, TrianglesColor, TrianglesPicture and PictureColor.
|
||||
type Canvas struct {
|
||||
gf *GLFrame
|
||||
shader *glShader
|
||||
shader *GLShader
|
||||
|
||||
cmp pixel.ComposeMethod
|
||||
mat mgl32.Mat3
|
||||
|
@ -39,9 +39,8 @@ func NewCanvas(bounds pixel.Rect) *Canvas {
|
|||
col: mgl32.Vec4{1, 1, 1, 1},
|
||||
}
|
||||
|
||||
baseShader(c)
|
||||
c.shader = NewGLShader(baseCanvasFragmentShader)
|
||||
c.SetBounds(bounds)
|
||||
c.shader.update()
|
||||
return c
|
||||
}
|
||||
|
||||
|
@ -49,22 +48,28 @@ func NewCanvas(bounds pixel.Rect) *Canvas {
|
|||
// 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.setUniform(name, value)
|
||||
c.shader.SetUniform(name, value)
|
||||
}
|
||||
|
||||
// SetFragmentShader allows you to set a new fragment shader on the underlying
|
||||
// framebuffer. Argument "src" is the GLSL source, not a filename.
|
||||
func (c *Canvas) SetFragmentShader(src string) {
|
||||
c.shader.fs = src
|
||||
c.shader.update()
|
||||
c.shader.Update()
|
||||
}
|
||||
|
||||
// MakeTriangles creates a specialized copy of the supplied Triangles that draws onto this Canvas.
|
||||
//
|
||||
// TrianglesPosition, TrianglesColor and TrianglesPicture are supported.
|
||||
func (c *Canvas) MakeTriangles(t pixel.Triangles) pixel.TargetTriangles {
|
||||
if gt, ok := t.(*GLTriangles); ok {
|
||||
return &canvasTriangles{
|
||||
GLTriangles: NewGLTriangles(c.shader.s, t),
|
||||
GLTriangles: gt,
|
||||
dst: c,
|
||||
}
|
||||
}
|
||||
return &canvasTriangles{
|
||||
GLTriangles: NewGLTriangles(c.shader, t),
|
||||
dst: c,
|
||||
}
|
||||
}
|
||||
|
@ -290,15 +295,15 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, bounds pixel.Rect) {
|
|||
setBlendFunc(cmp)
|
||||
|
||||
frame := ct.dst.gf.Frame()
|
||||
shader := ct.dst.shader.s
|
||||
shader := ct.shader.s
|
||||
|
||||
frame.Begin()
|
||||
shader.Begin()
|
||||
|
||||
ct.dst.shader.uniformDefaults.transform = mat
|
||||
ct.dst.shader.uniformDefaults.colormask = col
|
||||
ct.shader.uniformDefaults.transform = mat
|
||||
ct.shader.uniformDefaults.colormask = col
|
||||
dstBounds := ct.dst.Bounds()
|
||||
ct.dst.shader.uniformDefaults.bounds = mgl32.Vec4{
|
||||
ct.shader.uniformDefaults.bounds = mgl32.Vec4{
|
||||
float32(dstBounds.Min.X),
|
||||
float32(dstBounds.Min.Y),
|
||||
float32(dstBounds.W()),
|
||||
|
@ -306,15 +311,15 @@ func (ct *canvasTriangles) draw(tex *glhf.Texture, bounds pixel.Rect) {
|
|||
}
|
||||
|
||||
bx, by, bw, bh := intBounds(bounds)
|
||||
ct.dst.shader.uniformDefaults.texbounds = mgl32.Vec4{
|
||||
ct.shader.uniformDefaults.texbounds = mgl32.Vec4{
|
||||
float32(bx),
|
||||
float32(by),
|
||||
float32(bw),
|
||||
float32(bh),
|
||||
}
|
||||
|
||||
for loc, u := range ct.dst.shader.uniforms {
|
||||
ct.dst.shader.s.SetUniformAttr(loc, u.Value())
|
||||
for loc, u := range ct.shader.uniforms {
|
||||
ct.shader.s.SetUniformAttr(loc, u.Value())
|
||||
}
|
||||
|
||||
if clip, has := ct.ClipRect(); has {
|
||||
|
@ -360,17 +365,3 @@ func (cp *canvasPicture) Draw(t pixel.TargetTriangles) {
|
|||
}
|
||||
ct.draw(cp.GLPicture.Texture(), cp.GLPicture.Bounds())
|
||||
}
|
||||
|
||||
const (
|
||||
canvasPosition int = iota
|
||||
canvasColor
|
||||
canvasTexCoords
|
||||
canvasIntensity
|
||||
)
|
||||
|
||||
var defaultCanvasVertexFormat = glhf.AttrFormat{
|
||||
canvasPosition: {Name: "aPosition", Type: glhf.Vec2},
|
||||
canvasColor: {Name: "aColor", Type: glhf.Vec4},
|
||||
canvasTexCoords: {Name: "aTexCoords", Type: glhf.Vec2},
|
||||
canvasIntensity: {Name: "aIntensity", Type: glhf.Float},
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// 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
|
||||
// a per canvas basis.
|
||||
type glShader struct {
|
||||
type GLShader struct {
|
||||
s *glhf.Shader
|
||||
vf, uf glhf.AttrFormat
|
||||
vs, fs string
|
||||
|
@ -32,8 +32,42 @@ type gsUniformAttr struct {
|
|||
ispointer bool
|
||||
}
|
||||
|
||||
// reinitialize GLShader data and recompile the underlying gl shader object
|
||||
func (gs *glShader) update() {
|
||||
const (
|
||||
canvasPosition int = iota
|
||||
canvasColor
|
||||
canvasTexCoords
|
||||
canvasIntensity
|
||||
)
|
||||
|
||||
var defaultCanvasVertexFormat = glhf.AttrFormat{
|
||||
canvasPosition: {Name: "aPosition", Type: glhf.Vec2},
|
||||
canvasColor: {Name: "aColor", Type: glhf.Vec4},
|
||||
canvasTexCoords: {Name: "aTexCoords", Type: glhf.Vec2},
|
||||
canvasIntensity: {Name: "aIntensity", Type: glhf.Float},
|
||||
}
|
||||
|
||||
// Sets up a base shader with everything needed for a Pixel
|
||||
// canvas to render correctly. The defaults can be overridden
|
||||
// by simply using the SetUniform function.
|
||||
func NewGLShader(fragmentShader string) *GLShader {
|
||||
gs := &GLShader{
|
||||
vf: defaultCanvasVertexFormat,
|
||||
vs: baseCanvasVertexShader,
|
||||
fs: fragmentShader,
|
||||
}
|
||||
|
||||
gs.SetUniform("uTransform", &gs.uniformDefaults.transform)
|
||||
gs.SetUniform("uColorMask", &gs.uniformDefaults.colormask)
|
||||
gs.SetUniform("uBounds", &gs.uniformDefaults.bounds)
|
||||
gs.SetUniform("uTexBounds", &gs.uniformDefaults.texbounds)
|
||||
|
||||
gs.Update()
|
||||
|
||||
return gs
|
||||
}
|
||||
|
||||
// Update reinitialize GLShader data and recompile the underlying gl shader object
|
||||
func (gs *GLShader) Update() {
|
||||
gs.uf = nil
|
||||
for _, u := range gs.uniforms {
|
||||
gs.uf = append(gs.uf, glhf.Attr{
|
||||
|
@ -59,7 +93,7 @@ func (gs *glShader) update() {
|
|||
}
|
||||
|
||||
// gets the uniform index from GLShader
|
||||
func (gs *glShader) getUniform(Name string) int {
|
||||
func (gs *GLShader) getUniform(Name string) int {
|
||||
for i, u := range gs.uniforms {
|
||||
if u.Name == Name {
|
||||
return i
|
||||
|
@ -75,7 +109,7 @@ func (gs *glShader) getUniform(Name string) int {
|
|||
//
|
||||
// utime := float32(time.Since(starttime)).Seconds())
|
||||
// mycanvas.shader.AddUniform("u_time", &utime)
|
||||
func (gs *glShader) setUniform(name string, value interface{}) {
|
||||
func (gs *GLShader) SetUniform(name string, value interface{}) {
|
||||
t, p := getAttrType(value)
|
||||
if loc := gs.getUniform(name); loc > -1 {
|
||||
gs.uniforms[loc].Name = name
|
||||
|
@ -92,24 +126,6 @@ func (gs *glShader) setUniform(name string, value interface{}) {
|
|||
})
|
||||
}
|
||||
|
||||
// Sets up a base shader with everything needed for a Pixel
|
||||
// canvas to render correctly. The defaults can be overridden
|
||||
// by simply using the SetUniform function.
|
||||
func baseShader(c *Canvas) {
|
||||
gs := &glShader{
|
||||
vf: defaultCanvasVertexFormat,
|
||||
vs: baseCanvasVertexShader,
|
||||
fs: baseCanvasFragmentShader,
|
||||
}
|
||||
|
||||
gs.setUniform("uTransform", &gs.uniformDefaults.transform)
|
||||
gs.setUniform("uColorMask", &gs.uniformDefaults.colormask)
|
||||
gs.setUniform("uBounds", &gs.uniformDefaults.bounds)
|
||||
gs.setUniform("uTexBounds", &gs.uniformDefaults.texbounds)
|
||||
|
||||
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{} {
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
type GLTriangles struct {
|
||||
vs *glhf.VertexSlice
|
||||
data []float32
|
||||
shader *glhf.Shader
|
||||
shader *GLShader
|
||||
clip pixel.Rect
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,11 @@ var (
|
|||
// NewGLTriangles returns GLTriangles initialized with the data from the supplied Triangles.
|
||||
//
|
||||
// Only draw the Triangles using the provided Shader.
|
||||
func NewGLTriangles(shader *glhf.Shader, t pixel.Triangles) *GLTriangles {
|
||||
func NewGLTriangles(shader *GLShader, t pixel.Triangles) *GLTriangles {
|
||||
var gt *GLTriangles
|
||||
mainthread.Call(func() {
|
||||
gt = &GLTriangles{
|
||||
vs: glhf.MakeVertexSlice(shader, 0, t.Len()),
|
||||
vs: glhf.MakeVertexSlice(shader.s, 0, t.Len()),
|
||||
shader: shader,
|
||||
}
|
||||
})
|
||||
|
@ -49,7 +49,7 @@ func (gt *GLTriangles) VertexSlice() *glhf.VertexSlice {
|
|||
}
|
||||
|
||||
// Shader returns the GLTriangles's associated shader.
|
||||
func (gt *GLTriangles) Shader() *glhf.Shader {
|
||||
func (gt *GLTriangles) Shader() *GLShader {
|
||||
return gt.shader
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue