func newProgram(vertexShaderSource, fragmentShaderSource string) (uint32, error) { vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { return 0, err } fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { return 0, err } program := gl.CreateProgram() gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) var status int32 gl.GetProgramiv(program, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log)) return 0, errors.New(fmt.Sprintf("failed to link program: %v", log)) } gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) return program, nil }
func RegisterShader(name string, vertex, fragment []byte) error { if _, ok := shader_progs[name]; ok { return fmt.Errorf("Tried to register a shader called '%s' twice", name) } vertex_id := gl.CreateShader(gl.VERTEX_SHADER) pointer := &vertex[0] length := int32(len(vertex)) gl.ShaderSource(vertex_id, 1, (**int8)(unsafe.Pointer(&pointer)), &length) gl.CompileShader(vertex_id) var param int32 gl.GetShaderiv(vertex_id, gl.COMPILE_STATUS, ¶m) if param == 0 { buf := make([]byte, 5*1024) var length int32 gl.GetShaderInfoLog(vertex_id, int32(len(buf)), &length, (*int8)(unsafe.Pointer(&buf[0]))) if length > 0 { length-- } maxVersion := gl.GoStr(gl.GetString(gl.SHADING_LANGUAGE_VERSION)) return fmt.Errorf("Failed to compile vertex shader (max version supported: %q) %q: %q", maxVersion, name, buf[0:int(length)]) } fragment_id := gl.CreateShader(gl.FRAGMENT_SHADER) pointer = &fragment[0] length = int32(len(fragment)) gl.ShaderSource(fragment_id, 1, (**int8)(unsafe.Pointer(&pointer)), &length) gl.CompileShader(fragment_id) gl.GetShaderiv(fragment_id, gl.COMPILE_STATUS, ¶m) if param == 0 { buf := make([]byte, 5*1024) var length int32 gl.GetShaderInfoLog(fragment_id, int32(len(buf)), &length, (*int8)(unsafe.Pointer(&buf[0]))) if length > 0 { length-- } maxVersion := gl.GoStr(gl.GetString(gl.SHADING_LANGUAGE_VERSION)) return fmt.Errorf("Failed to compile fragment shader (max version supported: %q) %q: %q", maxVersion, name, buf[0:int(length)]) } // shader successfully compiled - now link program_id := gl.CreateProgram() gl.AttachShader(program_id, vertex_id) gl.AttachShader(program_id, fragment_id) gl.LinkProgram(program_id) gl.GetProgramiv(program_id, gl.LINK_STATUS, ¶m) if param == 0 { return fmt.Errorf("Failed to link shader '%s': %v", name, param) } shader_progs[name] = program_id return nil }