func (s *Shader) initWithString(vert_shader string, frag_shader string) { s.initShader(gl.VERTEX_SHADER, vert_shader, &s.vert_shader) s.initShader(gl.FRAGMENT_SHADER, frag_shader, &s.frag_shader) s.program = gl.CreateProgram() gl.AttachShader(s.program, s.vert_shader) gl.AttachShader(s.program, s.frag_shader) gl.LinkProgram(s.program) var ( status gl.Int info_length gl.Int message *gl.Char ) gl.GetProgramiv(s.program, gl.LINK_STATUS, &status) if status == gl.FALSE { fmt.Println("Error linking program") gl.GetProgramiv(s.program, gl.INFO_LOG_LENGTH, &info_length) message = gl.GLStringAlloc(gl.Sizei(info_length)) gl.GetProgramInfoLog(s.program, gl.Sizei(info_length), nil, message) fmt.Println(gl.GoString(message)) gl.GLStringFree(message) } s.initAttributes() s.initUniforms() }
// NewEffectFromDirectory creates a new Effect object based on the shader // directory given. func NewEffectFromDirectory(directory string) (*Effect, error) { effect := &Effect{} effect.uniforms = make(map[string]gl.Int) programID := gl.CreateProgram() var vscript, fscript []*gl.Char files, ioErr := ioutil.ReadDir(directory) if ioErr != nil { return effect, ioErr } for _, val := range files { name := val.Name() if shaderType := checkIfShaderFile(name); !val.IsDir() && shaderType != notShader { text, err := loadTextFile(directory + name) if err != nil { return effect, err } if shaderType == Vertex { vscript = append(vscript, text) } else if shaderType == Fragment { fscript = append(fscript, text) } } } vshaderID, vertErr := compileShader(Vertex, vscript) if vertErr != nil { return effect, vertErr } gl.AttachShader(programID, vshaderID) fshaderID, fragErr := compileShader(Fragment, fscript) if fragErr != nil { return effect, fragErr } gl.AttachShader(programID, fshaderID) gl.LinkProgram(programID) var status gl.Int gl.GetProgramiv(programID, gl.LINK_STATUS, &status) if status == gl.FALSE { return effect, errors.New("linking program") } effect.program = programID return effect, checkForErrors() }
// NewEffectFromStrings creates a new Effect object based on the given strings // containing GLSL shader script. The types values should correlate with the // type of shader the script is describing. func NewEffectFromStrings(text []string, types []ShaderType) (*Effect, error) { effect := &Effect{} effect.uniforms = make(map[string]gl.Int) programID := gl.CreateProgram() var vscript, fscript []*gl.Char for i, val := range text { if types[i] == Vertex { vscript = append(vscript, gl.GLString(val)) } else if types[i] == Fragment { fscript = append(fscript, gl.GLString(val)) } } vshaderID, vertErr := compileShader(Vertex, vscript) if vertErr != nil { return effect, vertErr } gl.AttachShader(programID, vshaderID) fshaderID, fragErr := compileShader(Fragment, fscript) if fragErr != nil { return effect, fragErr } gl.AttachShader(programID, fshaderID) gl.LinkProgram(programID) var status gl.Int gl.GetProgramiv(programID, gl.LINK_STATUS, &status) if status == gl.FALSE { return effect, errors.New("linking program") } effect.program = programID return effect, checkForErrors() }
func RegisterShader(name string, vertex, fragment []byte) error { if _, ok := shader_progs[name]; ok { return shaderError(fmt.Sprintf("Tried to register a shader called '%s' twice", name)) } vertex_id := gl.CreateShader(gl.VERTEX_SHADER) pointer := &vertex[0] length := gl.Int(len(vertex)) gl.ShaderSource(vertex_id, 1, (**gl.Char)(unsafe.Pointer(&pointer)), &length) gl.CompileShader(vertex_id) var param gl.Int gl.GetShaderiv(vertex_id, gl.COMPILE_STATUS, ¶m) if param == 0 { return shaderError(fmt.Sprintf("Failed to compile vertex shader '%s': %v", name, param)) } fragment_id := gl.CreateShader(gl.FRAGMENT_SHADER) pointer = &fragment[0] length = gl.Int(len(fragment)) gl.ShaderSource(fragment_id, 1, (**gl.Char)(unsafe.Pointer(&pointer)), &length) gl.CompileShader(fragment_id) gl.GetShaderiv(fragment_id, gl.COMPILE_STATUS, ¶m) if param == 0 { return shaderError(fmt.Sprintf("Failed to compile fragment shader '%s': %v", name, param)) } // 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 shaderError(fmt.Sprintf("Failed to link shader '%s': %v", name, param)) } shader_progs[name] = program_id return nil }
func InitShaders() { render.Queue(func() { vertex_shaders = make(map[string]uint32) fragment_shaders = make(map[string]uint32) shader_progs = make(map[string]uint32) warned_names = make(map[string]bool) RemoveRegistry("shaders") RegisterRegistry("shaders", make(map[string]*shaderDef)) RegisterAllObjectsInDir("shaders", filepath.Join(GetDataDir(), "shaders"), ".json", "json") names := GetAllNamesInRegistry("shaders") for _, name := range names { // Load the shader files shader := Shader{Defname: name} GetObject("shaders", &shader) vdata, err := ioutil.ReadFile(filepath.Join(GetDataDir(), shader.Vertex_path)) if err != nil { Error().Printf("Unable to load vertex shader '%s': %v", shader.Vertex_path, err) continue } fdata, err := ioutil.ReadFile(filepath.Join(GetDataDir(), shader.Fragment_path)) if err != nil { Error().Printf("Unable to load fragment shader '%s': %v", shader.Fragment_path, err) continue } // Create the vertex shader vertex_id, ok := vertex_shaders[shader.Vertex_path] if !ok { vertex_id = gl.CreateShader(gl.VERTEX_SHADER) pointer := &vdata[0] length := int32(len(vdata)) gl.ShaderSource(vertex_id, 1, (**gl.Char)(unsafe.Pointer(&pointer)), &length) gl.CompileShader(vertex_id) var param int32 gl.GetShaderiv(vertex_id, gl.COMPILE_STATUS, ¶m) if param == 0 { Error().Printf("Failed to compile vertex shader '%s': %v", shader.Vertex_path, param) continue } } // Create the fragment shader fragment_id, ok := fragment_shaders[shader.Fragment_path] if !ok { fragment_id = gl.CreateShader(gl.FRAGMENT_SHADER) pointer := &fdata[0] length := int32(len(fdata)) gl.ShaderSource(fragment_id, 1, (**gl.Char)(unsafe.Pointer(&pointer)), &length) gl.CompileShader(fragment_id) var param int32 gl.GetShaderiv(fragment_id, gl.COMPILE_STATUS, ¶m) if param == 0 { Error().Printf("Failed to compile fragment shader '%s': %v", shader.Fragment_path, param) continue } } // 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) var param int32 gl.GetProgramiv(program_id, gl.LINK_STATUS, ¶m) if param == 0 { Error().Printf("Failed to link shader '%s': %v", shader.Name, param) continue } vertex_shaders[shader.Vertex_path] = vertex_id fragment_shaders[shader.Fragment_path] = fragment_id shader_progs[shader.Name] = program_id } }) }