From d53eefbf59d2e45c4d7c45207469d34f2ed8d967 Mon Sep 17 00:00:00 2001 From: faiface Date: Wed, 30 Nov 2016 17:41:48 +0100 Subject: [PATCH] shader uniforms --- pixelgl/shader.go | 28 ++++++++++++++++++++++++---- pixelgl/vertex.go | 10 ++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/pixelgl/shader.go b/pixelgl/shader.go index 134f4c4..858894a 100644 --- a/pixelgl/shader.go +++ b/pixelgl/shader.go @@ -7,18 +7,29 @@ import ( "github.com/pkg/errors" ) +// UniformFormat defines names, purposes and types of uniform variables inside a shader. +// +// Example: +// +// UniformFormat{"transform": {Transform, Mat3}, "camera": {Camera, Mat3}} +type UniformFormat map[string]Attr + // Shader is an OpenGL shader program. type Shader struct { - parent Doer - program uint32 + parent Doer + format UniformFormat + program uint32 + uniforms map[Attr]int32 } // NewShader creates a new shader program from the specified vertex shader and fragment shader sources. // // Note that vertexShader and fragmentShader parameters must contain the source code, they're not filenames. -func NewShader(parent Doer, vertexShader, fragmentShader string) (*Shader, error) { +func NewShader(parent Doer, format UniformFormat, vertexShader, fragmentShader string) (*Shader, error) { shader := &Shader{ - parent: parent, + parent: parent, + format: format, + uniforms: make(map[Attr]int32), } var err, glerr error @@ -87,6 +98,15 @@ func NewShader(parent Doer, vertexShader, fragmentShader string) (*Shader, error gl.DeleteShader(vshader) gl.DeleteShader(fshader) + // uniforms + for uname, utype := range format { + ulocation := gl.GetUniformLocation(shader.program, gl.Str(uname+"\x00")) + if ulocation == -1 { + return fmt.Errorf("shader does not contain uniform '%s'", uname) + } + shader.uniforms[utype] = ulocation + } + return nil }) }) diff --git a/pixelgl/vertex.go b/pixelgl/vertex.go index 30e8277..9cd4a59 100644 --- a/pixelgl/vertex.go +++ b/pixelgl/vertex.go @@ -12,6 +12,8 @@ import ( // Example: // // VertexFormat{{Position, Vec2}, {Color, Vec4}, {TexCoord, Vec2}, {Visible, Bool}} +// +// Note: vertex array currently doesn't support matrices in vertex format. type VertexFormat []Attr // Size calculates the total size of a single vertex in this vertex format (sum of the sizes of all vertex attributes). @@ -226,12 +228,15 @@ func (va *VertexArray) SetVertex(vertex int, data unsafe.Pointer) { // SetVertexAttribute sets the value of the specified vertex attribute of the specified vertex. // Argument data must point to a slice/array containing the new attribute data. -func (va *VertexArray) SetVertexAttribute(vertex int, attr Attr, data unsafe.Pointer) { +// +// This function returns false if the specified attribute does not exist. Note that the function panics +// if the vertex is out of range. +func (va *VertexArray) SetVertexAttribute(vertex int, attr Attr, data unsafe.Pointer) (ok bool) { if vertex < 0 || vertex >= va.count { panic("set vertex attribute error: invalid vertex index") } if _, ok := va.attrs[attr]; !ok { - return // ignore non-existing attributes + return false } DoNoBlock(func() { gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo) @@ -245,6 +250,7 @@ func (va *VertexArray) SetVertexAttribute(vertex int, attr Attr, data unsafe.Poi panic(errors.Wrap(err, "set attribute vertex error")) } }) + return true } // Do binds a vertex arrray and it's associated vertex buffer, executes sub, and unbinds the vertex array and it's vertex buffer.