util.go raw
1 // SPDX-License-Identifier: Unlicense OR MIT
2
3 package gl
4
5 import (
6 "errors"
7 "fmt"
8 "strings"
9 )
10
11 func CreateProgram(ctx *Functions, vsSrc, fsSrc string, attribs []string) (Program, error) {
12 vs, err := createShader(ctx, VERTEX_SHADER, vsSrc)
13 if err != nil {
14 return Program{}, err
15 }
16 defer ctx.DeleteShader(vs)
17 fs, err := createShader(ctx, FRAGMENT_SHADER, fsSrc)
18 if err != nil {
19 return Program{}, err
20 }
21 defer ctx.DeleteShader(fs)
22 prog := ctx.CreateProgram()
23 if !prog.Valid() {
24 return Program{}, errors.New("glCreateProgram failed")
25 }
26 ctx.AttachShader(prog, vs)
27 ctx.AttachShader(prog, fs)
28 for i, a := range attribs {
29 ctx.BindAttribLocation(prog, Attrib(i), a)
30 }
31 ctx.LinkProgram(prog)
32 if ctx.GetProgrami(prog, LINK_STATUS) == 0 {
33 log := ctx.GetProgramInfoLog(prog)
34 ctx.DeleteProgram(prog)
35 return Program{}, fmt.Errorf("program link failed: %s", strings.TrimSpace(log))
36 }
37 return prog, nil
38 }
39
40 func CreateComputeProgram(ctx *Functions, src string) (Program, error) {
41 cs, err := createShader(ctx, COMPUTE_SHADER, src)
42 if err != nil {
43 return Program{}, err
44 }
45 defer ctx.DeleteShader(cs)
46 prog := ctx.CreateProgram()
47 if !prog.Valid() {
48 return Program{}, errors.New("glCreateProgram failed")
49 }
50 ctx.AttachShader(prog, cs)
51 ctx.LinkProgram(prog)
52 if ctx.GetProgrami(prog, LINK_STATUS) == 0 {
53 log := ctx.GetProgramInfoLog(prog)
54 ctx.DeleteProgram(prog)
55 return Program{}, fmt.Errorf("program link failed: %s", strings.TrimSpace(log))
56 }
57 return prog, nil
58 }
59
60 func createShader(ctx *Functions, typ Enum, src string) (Shader, error) {
61 sh := ctx.CreateShader(typ)
62 if !sh.Valid() {
63 return Shader{}, errors.New("glCreateShader failed")
64 }
65 ctx.ShaderSource(sh, src)
66 ctx.CompileShader(sh)
67 if ctx.GetShaderi(sh, COMPILE_STATUS) == 0 {
68 log := ctx.GetShaderInfoLog(sh)
69 ctx.DeleteShader(sh)
70 return Shader{}, fmt.Errorf("shader compilation failed: %s", strings.TrimSpace(log))
71 }
72 return sh, nil
73 }
74
75 func ParseGLVersion(glVer string) (version [2]int, gles bool, err error) {
76 var ver [2]int
77 if _, err := fmt.Sscanf(glVer, "OpenGL ES %d.%d", &ver[0], &ver[1]); err == nil {
78 return ver, true, nil
79 } else if _, err := fmt.Sscanf(glVer, "WebGL %d.%d", &ver[0], &ver[1]); err == nil {
80 // WebGL major version v corresponds to OpenGL ES version v + 1
81 ver[0]++
82 return ver, true, nil
83 } else if _, err := fmt.Sscanf(glVer, "%d.%d", &ver[0], &ver[1]); err == nil {
84 return ver, false, nil
85 }
86 return ver, false, fmt.Errorf("failed to parse OpenGL ES version (%s)", glVer)
87 }
88