func compileShader(code string, shaderType gl.Enum) (gl.Uint, error) { shader := gl.CreateShader(shaderType) glCode := gl.GLString(code) defer gl.GLStringFree(glCode) gl.ShaderSource(shader, 1, &glCode, nil) gl.CompileShader(shader) var status gl.Int gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status) if status == 0 { var logLength gl.Int gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength) msg := gl.GLStringAlloc(gl.Sizei(logLength)) defer gl.GLStringFree(msg) gl.GetShaderInfoLog(shader, gl.Sizei(logLength), nil, msg) gl.DeleteShader(shader) return 0, errors.New(gl.GoString(msg)) } return shader, nil }
func newGL32Shader(name, vertexCode, fragmentCode string) (*gl32Shader, error) { vertexShader, err := compileShader(vertexCode, gl.VERTEX_SHADER) if err != nil { return nil, err } fragmentShader, err := compileShader(fragmentCode, gl.FRAGMENT_SHADER) if err != nil { return nil, err } shader := &gl32Shader{name, gl.CreateProgram(), nil} gl.AttachShader(shader.program, vertexShader) gl.AttachShader(shader.program, fragmentShader) gl.BindAttribLocation(shader.program, ATTRIB_POSITION, gl.GLString("position")) gl.BindAttribLocation(shader.program, ATTRIB_NORMAL, gl.GLString("normal")) gl.BindAttribLocation(shader.program, ATTRIB_UV0, gl.GLString("uv0")) gl.BindAttribLocation(shader.program, ATTRIB_UV1, gl.GLString("uv1")) gl.BindAttribLocation(shader.program, ATTRIB_UV2, gl.GLString("uv2")) gl.BindAttribLocation(shader.program, ATTRIB_UV3, gl.GLString("uv3")) gl.BindAttribLocation(shader.program, ATTRIB_COLOR, gl.GLString("color")) gl.LinkProgram(shader.program) var status gl.Int gl.GetProgramiv(shader.program, gl.LINK_STATUS, &status) if status != 1 { gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) gl.DeleteProgram(shader.program) return nil, errors.New(fmt.Sprintf("Could not link shader program '%s'", name)) } shader.buildUniformList() return shader, nil }