From 832425c6cc5452620058e1e21988b74a6507ff71 Mon Sep 17 00:00:00 2001
From: faiface <faiface@ksp.sk>
Date: Wed, 23 Nov 2016 20:06:34 +0100
Subject: [PATCH] add resource delete methods

---
 pixelgl/shader.go  | 122 +++++++++++++++++++++++++++++++++++++++++++++
 pixelgl/texture.go |   7 +++
 pixelgl/vertex.go  |   8 +++
 3 files changed, 137 insertions(+)
 create mode 100644 pixelgl/shader.go

diff --git a/pixelgl/shader.go b/pixelgl/shader.go
new file mode 100644
index 0000000..bcd0d94
--- /dev/null
+++ b/pixelgl/shader.go
@@ -0,0 +1,122 @@
+package pixelgl
+
+import (
+	"fmt"
+
+	"github.com/go-gl/gl/v3.3-core/gl"
+	"github.com/pkg/errors"
+)
+
+// Shader is an OpenGL shader program.
+type Shader struct {
+	parent  BeginEnder
+	program uint32
+}
+
+// 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 BeginEnder, vertexShader, fragmentShader string) (*Shader, error) {
+	shader := &Shader{
+		parent: parent,
+	}
+	err, glerr := DoErrGLErr(func() error {
+		var vshader, fshader uint32
+
+		// vertex shader
+		{
+			vshader = gl.CreateShader(gl.VERTEX_SHADER)
+			src, free := gl.Strs(vertexShader)
+			defer free()
+			length := int32(len(vertexShader))
+			gl.ShaderSource(vshader, 1, src, &length)
+			gl.CompileShader(vshader)
+
+			var (
+				success int32
+				infoLog = make([]byte, 512)
+			)
+			gl.GetShaderiv(vshader, gl.COMPILE_STATUS, &success)
+			if success == 0 {
+				gl.GetShaderInfoLog(vshader, int32(len(infoLog)), nil, &infoLog[0])
+				return fmt.Errorf("error compiling vertex shader: %s", string(infoLog))
+			}
+		}
+
+		// fragment shader
+		{
+			fshader = gl.CreateShader(gl.FRAGMENT_SHADER)
+			src, free := gl.Strs(fragmentShader)
+			defer free()
+			length := int32(len(fragmentShader))
+			gl.ShaderSource(fshader, 1, src, &length)
+			gl.CompileShader(fshader)
+
+			var (
+				success int32
+				infoLog = make([]byte, 512)
+			)
+			gl.GetShaderiv(fshader, gl.COMPILE_STATUS, &success)
+			if success == 0 {
+				gl.GetShaderInfoLog(fshader, int32(len(infoLog)), nil, &infoLog[0])
+				return fmt.Errorf("error compiling fragment shader: %s", string(infoLog))
+			}
+		}
+
+		// shader program
+		{
+			shader.program = gl.CreateProgram()
+			gl.AttachShader(shader.program, vshader)
+			gl.AttachShader(shader.program, fshader)
+			gl.LinkProgram(shader.program)
+
+			var (
+				success int32
+				infoLog = make([]byte, 512)
+			)
+			gl.GetProgramiv(shader.program, gl.LINK_STATUS, &success)
+			if success == 0 {
+				gl.GetProgramInfoLog(shader.program, int32(len(infoLog)), nil, &infoLog[0])
+				return fmt.Errorf("error linking shader program: %s", string(infoLog))
+			}
+		}
+
+		gl.DeleteShader(vshader)
+		gl.DeleteShader(fshader)
+
+		return nil
+	})
+	if err != nil {
+		if glerr != nil {
+			err = errors.Wrap(glerr, err.Error())
+		}
+		return nil, err
+	}
+	if glerr != nil {
+		return nil, glerr
+	}
+	return shader, nil
+}
+
+// Delete deletes a shader program. Don't use a shader after deletion.
+func (s *Shader) Delete() {
+	Do(func() {
+		gl.DeleteProgram(s.program)
+	})
+}
+
+// Begin starts using a shader program.
+func (s *Shader) Begin() {
+	s.parent.Begin()
+	Do(func() {
+		gl.UseProgram(s.program)
+	})
+}
+
+// End stops using a shader program.
+func (s *Shader) End() {
+	Do(func() {
+		gl.UseProgram(0)
+	})
+	s.parent.End()
+}
diff --git a/pixelgl/texture.go b/pixelgl/texture.go
index d9cad7b..0218730 100644
--- a/pixelgl/texture.go
+++ b/pixelgl/texture.go
@@ -40,6 +40,13 @@ func NewTexture(parent BeginEnder, width, height int, pixels []uint8) (*Texture,
 	return texture, nil
 }
 
+// Delete deletes a texture. Don't use a texture after deletion.
+func (t *Texture) Delete() {
+	Do(func() {
+		gl.DeleteTextures(1, &t.tex)
+	})
+}
+
 // Begin binds a texture.
 func (t *Texture) Begin() {
 	t.parent.Begin()
diff --git a/pixelgl/vertex.go b/pixelgl/vertex.go
index 63cc498..2b17260 100644
--- a/pixelgl/vertex.go
+++ b/pixelgl/vertex.go
@@ -139,6 +139,14 @@ func NewVertexArray(parent BeginEnder, format VertexFormat, mode VertexDrawMode,
 	return va, nil
 }
 
+// Delete deletes a vertex array and it's associated vertex buffer. Don't use a vertex array after deletion.
+func (va *VertexArray) Delete() {
+	Do(func() {
+		gl.DeleteVertexArrays(1, &va.vao)
+		gl.DeleteBuffers(1, &va.vbo)
+	})
+}
+
 // VertexFormat returns the format of the vertices inside a vertex array.
 //
 // Do not change this format!
-- 
GitLab