func (self *ShaderInfo) CompileShader() (uint32, error) { content, err := ioutil.ReadFile(self.Path) if err != nil { return 0, err } contentString := bytes.NewBuffer(content).String() glContentString := gl.Str(contentString + "\x00") shader := gl.CreateShader(self.ShaderType) gl.ShaderSource(shader, 1, &glContentString, 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", contentString, log) } return shader, nil }
// loads shader objects and then attaches them to a program func LoadShaderProgram(vertShader string, fragShader string, attribs []string) (*Program, error) { // create the program var prog uint32 = gl.CreateProgram() var p *Program = &Program{prog, make(map[string]int32)} // create the vertex shader var vs uint32 = gl.CreateShader(gl.VERTEX_SHADER) ShaderSource(vs, vertShader) gl.CompileShader(vs) var success int32 = gl.FALSE gl.GetShaderiv(vs, gl.COMPILE_STATUS, &success) if success == gl.FALSE { return nil, fmt.Errorf("Failed to compile the vertex shader!\n%s", GetShaderInfoLog(vs)) } // create the fragment shader var fs uint32 = gl.CreateShader(gl.FRAGMENT_SHADER) ShaderSource(fs, fragShader) gl.CompileShader(fs) success = gl.FALSE gl.GetShaderiv(fs, gl.COMPILE_STATUS, &success) if success == gl.FALSE { return nil, fmt.Errorf("Failed to compile the fragment shader!\n%s", GetShaderInfoLog(fs)) } // attach the shaders to the program and link gl.AttachShader(prog, vs) gl.AttachShader(prog, fs) for i := 1; i <= len(attribs); i++ { var attr_array []uint8 = StringToArray(attribs[i-1]) gl.BindAttribLocation(prog, uint32(i), &attr_array[0]) } gl.LinkProgram(prog) success = gl.FALSE gl.GetProgramiv(prog, gl.LINK_STATUS, &success) if success == gl.FALSE { return nil, fmt.Errorf("Failed to link the program!\n%s", p.GetProgramInfoLog()) } // at this point the shaders can be deleted gl.DeleteShader(vs) gl.DeleteShader(fs) return p, nil }
func GetShaderInfoLog(shader uint32) string { var logSize int32 = 0 gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logSize) var infoLog []uint8 = make([]uint8, logSize) gl.GetShaderInfoLog(shader, logSize, &logSize, &infoLog[0]) return gl.GoStr(&infoLog[0]) }
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 }