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, (**uint8)(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, (*uint8)(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, (**uint8)(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, (*uint8)(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 }
func compileShader(sourceFile string, shaderType uint32) (uint32, error) { // read shader source from file sourceBytes, err := ioutil.ReadFile(sourceFile) if err != nil { return 0, err } // allow use as a C string csource := gl.Str(string(sourceBytes) + "\x00") // load into OpenGL shader := gl.CreateShader(shaderType) gl.ShaderSource(shader, 1, &csource, nil) gl.CompileShader(shader) // error handling var status int32 gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log)) return 0, fmt.Errorf("failed to compile %v: %v", sourceFile, log) } return shader, nil }
// Attempting to load a single shader. func LoadShader(path string, shaderType uint32) (Shader, error, bool) { // Loading in the file contents. file, err := os.Open(path) if err != nil { return 0, err, false } defer file.Close() contentBytes, err := ioutil.ReadAll(file) if err != nil { return 0, err, false } content := gl.Str(string(contentBytes) + "\x00") // Creating and compiling the shader. shader := gl.CreateShader(shaderType) gl.ShaderSource(shader, 1, &content, nil) gl.CompileShader(shader) var compiled int32 gl.GetShaderiv(shader, gl.COMPILE_STATUS, &compiled) if compiled == gl.FALSE { var length int32 gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &length) log := strings.Repeat("\x00", int(length+1)) gl.GetShaderInfoLog(shader, length, nil, gl.Str(log)) return 0, errors.New("Shader failed to compile: " + log), true } return Shader(shader), nil, false }
func CompileShader(stype uint32, source string) (shader uint32, err error) { csource := gl.Str(source) shader = gl.CreateShader(stype) gl.ShaderSource(shader, 1, &csource, nil) gl.CompileShader(shader) var status int32 if gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status); status == gl.FALSE { var length int32 gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &length) log := strings.Repeat("\x00", int(length+1)) gl.GetShaderInfoLog(shader, length, nil, gl.Str(log)) err = fmt.Errorf("ERROR shader compile:\n%s", log) } return }
func compileShader(source string, shaderType uint32) (uint32, error) { shader := gl.CreateShader(shaderType) csource := gl.Str(source) gl.ShaderSource(shader, 1, &csource, nil) gl.CompileShader(shader) var status int32 gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log)) return 0, fmt.Errorf("failed to compile %v: %v", source, log) } return shader, nil }
func InitShader(shader graphics.ShaderSource) (uint32, error) { //vertexshader vertexShaderHandle := gl.CreateShader(gl.VERTEX_SHADER) defer gl.DeleteShader(vertexShaderHandle) vertText := gl.Str(shader.GetVertexSource()) gl.ShaderSource(vertexShaderHandle, 1, &vertText, nil) gl.CompileShader(vertexShaderHandle) //error handling var isVertexCompiled int32 gl.GetShaderiv(vertexShaderHandle, gl.COMPILE_STATUS, &isVertexCompiled) if isVertexCompiled == gl.FALSE { var maxLength int32 gl.GetShaderiv(vertexShaderHandle, gl.INFO_LOG_LENGTH, &maxLength) log := strings.Repeat("\x00", int(maxLength+1)) gl.GetShaderInfoLog(vertexShaderHandle, maxLength, nil, gl.Str(log)) gl.DeleteShader(vertexShaderHandle) fmt.Println("Vertex shader compile error") fmt.Println(log) return 0, errors.New("Vertex shader compile error") } //fragment shader fragmentShaderHandle := gl.CreateShader(gl.FRAGMENT_SHADER) defer gl.DeleteShader(fragmentShaderHandle) fragText := gl.Str(shader.GetFragmentSource()) gl.ShaderSource(fragmentShaderHandle, 1, &fragText, nil) gl.CompileShader(fragmentShaderHandle) //error handling var isFragmentCompiled int32 gl.GetShaderiv(fragmentShaderHandle, gl.COMPILE_STATUS, &isFragmentCompiled) if isFragmentCompiled == gl.FALSE { var maxLength int32 gl.GetShaderiv(fragmentShaderHandle, gl.INFO_LOG_LENGTH, &maxLength) log := strings.Repeat("\x00", int(maxLength+1)) gl.GetShaderInfoLog(fragmentShaderHandle, maxLength, nil, gl.Str(log)) gl.DeleteShader(fragmentShaderHandle) fmt.Println("Fragment shader compile error") fmt.Println(log) return 0, errors.New("Fragment shader compile error") } //program shader shaderHandle := gl.CreateProgram() gl.AttachShader(shaderHandle, vertexShaderHandle) gl.AttachShader(shaderHandle, fragmentShaderHandle) gl.LinkProgram(shaderHandle) //error handling var isLinked int32 gl.GetProgramiv(shaderHandle, gl.LINK_STATUS, &isLinked) if isLinked == gl.FALSE { var maxLength int32 gl.GetProgramiv(shaderHandle, gl.INFO_LOG_LENGTH, &maxLength) log := strings.Repeat("\x00", int(maxLength+1)) gl.GetProgramInfoLog(shaderHandle, maxLength, nil, gl.Str(log)) gl.DeleteProgram(shaderHandle) fmt.Println("Shader linking error") fmt.Println(log) return 0, errors.New("Shader linking error") } return shaderHandle, nil }
// LoadShaderProgram loads shader objects and then attaches them to a program func LoadShaderProgram(vertShader, fragShader string) (uint32, error) { // create the program prog := gl.CreateProgram() // create the vertex shader vs := gl.CreateShader(gl.VERTEX_SHADER) cVertShader, free := gl.Strs(vertShader + "\x00") gl.ShaderSource(vs, 1, cVertShader, nil) gl.CompileShader(vs) free() var status int32 gl.GetShaderiv(vs, gl.COMPILE_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetShaderiv(vs, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetShaderInfoLog(vs, logLength, nil, gl.Str(log)) err := fmt.Sprintf("Failed to compile the vertex shader!\n%s", log) fmt.Println(err) return 0, errors.New(err) } defer gl.DeleteShader(vs) // create the fragment shader fs := gl.CreateShader(gl.FRAGMENT_SHADER) cFragShader, free := gl.Strs(fragShader + "\x00") gl.ShaderSource(fs, 1, cFragShader, nil) gl.CompileShader(fs) free() gl.GetShaderiv(fs, gl.COMPILE_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetShaderiv(fs, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetShaderInfoLog(fs, logLength, nil, gl.Str(log)) err := fmt.Sprintf("Failed to compile the fragment shader!\n%s", log) fmt.Println(err) return 0, errors.New(err) } defer gl.DeleteShader(fs) // attach the shaders to the program and link // attach the shaders to the program and link gl.AttachShader(prog, vs) gl.AttachShader(prog, fs) gl.LinkProgram(prog) gl.GetProgramiv(prog, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(prog, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(prog, logLength, nil, gl.Str(log)) error := fmt.Sprintf("Failed to link the program!\n%s", log) fmt.Println(error) return 0, errors.New(error) } return prog, nil }