github.com/Seikaijyu/gio@v0.0.1/internal/gl/util.go (about) 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 }