commit 235a82b16717a311840e0086b9e16b22f9756269
parent bdcf1967a838b2f2c0b5fc73c9a0c206c4e83195
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 19 Oct 2024 14:05:55 +0900
make Shader struct
Diffstat:
5 files changed, 116 insertions(+), 71 deletions(-)
diff --git a/cmd/sample/fragment.glsl b/cmd/sample/fragment.glsl
@@ -0,0 +1,8 @@
+
+#version 330 core
+in vec3 vcol;
+out vec4 fcol;
+void main() {
+ fcol = vec4(vcol, 1);
+}
+
diff --git a/cmd/sample/main.go b/cmd/sample/main.go
@@ -1,14 +1,15 @@
package main
import (
- "fmt"
"log"
"math"
+ "path/filepath"
"runtime"
- "strings"
"github.com/go-gl/gl/v3.3-core/gl"
"github.com/go-gl/glfw/v3.3/glfw"
+
+ "git.mtkn.jp/draw"
)
const (
@@ -32,69 +33,17 @@ func processInput(w *glfw.Window) {
}
}
-func newShader(src string, xtype uint32) (shader uint32, err error) {
- shader = gl.CreateShader(xtype)
- cstrs, free := gl.Strs(src + "\x00")
- defer free()
- gl.ShaderSource(shader, 1, cstrs, nil)
- gl.CompileShader(shader)
-
- var success int32
- gl.GetShaderiv(shader, gl.COMPILE_STATUS, &success)
- if success == gl.FALSE {
- var logLength int32
- gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength)
- l := gl.Str(strings.Repeat("\x00", int(logLength)))
- gl.GetShaderInfoLog(shader, logLength, nil, l)
- gl.DeleteShader(shader)
- return 0, fmt.Errorf("%v", gl.GoStr(l))
- }
- return shader, nil
-}
-
-func linkShaders(vertexShader, fragmentShader uint32) (shader uint32, err error) {
- shader = gl.CreateProgram()
- gl.AttachShader(shader, vertexShader)
- gl.AttachShader(shader, fragmentShader)
- gl.LinkProgram(shader)
-
- var success int32
- gl.GetProgramiv(shader, gl.LINK_STATUS, &success)
- if success == gl.FALSE {
- var logLength int32
- gl.GetProgramiv(shader, gl.INFO_LOG_LENGTH, &logLength)
- l := gl.Str(strings.Repeat("\x00", int(logLength)))
- gl.GetProgramInfoLog(shader, logLength, nil, l)
- return 0, fmt.Errorf("%v", gl.GoStr(l))
- }
- return shader, nil
-}
-
var vertices = []float32{
- -0.5, -0.5, 0.0,
- 0.5, -0.5, 0.0,
- 0.0, 0.5, 0.0,
+ // positions, colors
+ -0.5, -0.5, 0.0, 1, 0, 0,
+ 0.5, -0.5, 0.0, 0, 1, 0,
+ 0.0, 0.5, 0.0, 0, 0, 1,
}
var indices = []uint32{
0, 1, 2,
}
-const vertexShaderSource = `#version 330 core
-layout (location = 0) in vec3 aPos;
-void main() {
- gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
-}
-`
-
-const fragmentShaderSource = `#version 330 core
-out vec4 FragColor;
-
-void main() {
- FragColor = vec4(1.0, 0.5, 0.2, 1.0);
-}
-`
-
func main() {
err := glfw.Init()
if err != nil {
@@ -115,20 +64,17 @@ func main() {
}
gl.Viewport(0, 0, winW, winH)
- vertexShader, err := newShader(vertexShaderSource, gl.VERTEX_SHADER)
- if err != nil {
- log.Fatalf("crete vertex shader: %v", err)
- }
- fragmentShader, err := newShader(fragmentShaderSource, gl.FRAGMENT_SHADER)
- if err != nil {
- log.Fatalf("crete fragment shader: %v", err)
+ _, f, _, ok := runtime.Caller(0)
+ if !ok {
+ log.Fatalf("unable to get source file information")
}
- shaderProgram, err := linkShaders(vertexShader, fragmentShader)
+ vpath := filepath.Join(filepath.Dir(f), "vertex.glsl")
+ fpath := filepath.Join(filepath.Dir(f), "fragment.glsl")
+
+ shader, err := draw.NewShader(vpath, fpath)
if err != nil {
- log.Fatalf("link shaders: %v", err)
+ log.Fatalf("create shader: %v", err)
}
- gl.DeleteShader(vertexShader)
- gl.DeleteShader(fragmentShader)
var VBO, VAO, EBO uint32
gl.GenVertexArrays(1, &VAO)
@@ -141,18 +87,20 @@ func main() {
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, EBO)
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices) * 4,
gl.Ptr(indices), gl.STATIC_DRAW)
- gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 3*4, nil)
+ gl.VertexAttribPointerWithOffset(0, 3, gl.FLOAT, false, 6*4, 0)
gl.EnableVertexAttribArray(0)
+ gl.VertexAttribPointerWithOffset(1, 3, gl.FLOAT, false, 6*4, 3*4)
+ gl.EnableVertexAttribArray(1)
gl.BindBuffer(gl.ARRAY_BUFFER, 0);
gl.BindVertexArray(0)
window.SetFramebufferSizeCallback(framebufferSizeCallback)
+ shader.Use()
for !window.ShouldClose() {
processInput(window)
gl.ClearColor(0.2, 0.3, 0.3, 1.0)
gl.Clear(gl.COLOR_BUFFER_BIT)
- gl.UseProgram(shaderProgram)
gl.BindVertexArray(VAO)
gl.DrawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, nil)
window.SwapBuffers()
diff --git a/cmd/sample/vertex.glsl b/cmd/sample/vertex.glsl
@@ -0,0 +1,9 @@
+#version 330 core
+layout (location = 0) in vec3 pos;
+layout (location = 1) in vec3 col;
+out vec3 vcol;
+void main() {
+ gl_Position = vec4(pos.x, -pos.y, pos.z, 1.0);
+ vcol = col;
+}
+
diff --git a/shader.go b/shader.go
@@ -0,0 +1,80 @@
+package draw
+
+import (
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/go-gl/gl/v3.3-core/gl"
+)
+
+func compileShader(path string, xtype uint32) (shaderID uint32, err error) {
+ src, err := os.ReadFile(path)
+ if err != nil {
+ return 0, fmt.Errorf("readfile %s: %v", path, err)
+ }
+ shaderID = gl.CreateShader(xtype)
+ if shaderID == 0 {
+ return 0, fmt.Errorf("can't create shader")
+ }
+ cstrs, free := gl.Strs(string(src) + "\x00")
+ defer free()
+ gl.ShaderSource(shaderID, 1, cstrs, nil)
+ gl.CompileShader(shaderID)
+
+ var success int32
+ gl.GetShaderiv(shaderID, gl.COMPILE_STATUS, &success)
+ if success == gl.FALSE {
+ var logLength int32
+ gl.GetShaderiv(shaderID, gl.INFO_LOG_LENGTH, &logLength)
+ l := gl.Str(strings.Repeat("\x00", int(logLength)))
+ gl.GetShaderInfoLog(shaderID, logLength, nil, l)
+ gl.DeleteShader(shaderID)
+ return 0, fmt.Errorf("%v", gl.GoStr(l))
+ }
+ return shaderID, nil
+}
+
+func linkShaders(vsID, fsID uint32) (shaderID uint32, err error) {
+ shaderID = gl.CreateProgram()
+ gl.AttachShader(shaderID, vsID)
+ gl.AttachShader(shaderID, fsID)
+ gl.LinkProgram(shaderID)
+
+ var success int32
+ gl.GetProgramiv(shaderID, gl.LINK_STATUS, &success)
+ if success == gl.FALSE {
+ var logLength int32
+ gl.GetProgramiv(shaderID, gl.INFO_LOG_LENGTH, &logLength)
+ l := gl.Str(strings.Repeat("\x00", int(logLength)))
+ gl.GetProgramInfoLog(shaderID, logLength, nil, l)
+ return 0, fmt.Errorf("%v", gl.GoStr(l))
+ }
+ return shaderID, nil
+}
+
+type Shader struct {
+ id uint32
+}
+
+func NewShader(vpath, fpath string) (*Shader, error) {
+ vid, err := compileShader(vpath, gl.VERTEX_SHADER)
+ if err != nil {
+ return nil, fmt.Errorf("compile vertex shader: %v", err)
+ }
+ fid, err := compileShader(fpath, gl.FRAGMENT_SHADER)
+ if err != nil {
+ return nil, fmt.Errorf("compile fragment shader: %v", err)
+ }
+ sid, err := linkShaders(vid, fid)
+ if err != nil {
+ return nil, fmt.Errorf("link shaders: %v", err)
+ }
+ gl.DeleteShader(vid)
+ gl.DeleteShader(fid)
+ return &Shader{id: sid}, nil
+}
+
+func (s *Shader) Use() {
+ gl.UseProgram(s.id)
+}
diff --git a/test.png b/test.png
Binary files differ.