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, fmt.Errorf("failed to link program: %v", log) } gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) return program, nil }
// Attempting to load a ShaderProgram from a given location on the disk. It // looks for file starting at the path, and then with the respective suffixes of // .vert, .frag, and .geom. func LoadShaderProgram(path string) (ShaderProgram, error) { loaded := 0 // Loading the vertex shader. vert, err, major := LoadShader(path+".vert", gl.VERTEX_SHADER) handleShaderLoad("vert", err, major, &loaded) // Loading the fragment shader. frag, err, major := LoadShader(path+".frag", gl.FRAGMENT_SHADER) handleShaderLoad("frag", err, major, &loaded) // Loading the geometry shader. geom, err, major := LoadShader(path+".geom", gl.GEOMETRY_SHADER) handleShaderLoad("geom", err, major, &loaded) // Making sure we've loaded any shaders. if loaded == 0 { return 0, errors.New("Cannot make a shader program without any shaders.") } // Creating a loopable structure of the shaders. shaders := []uint32{ uint32(vert), uint32(frag), uint32(geom), } program := gl.CreateProgram() for _, shader := range shaders { gl.AttachShader(program, shader) } gl.LinkProgram(program) // Destroying the shaders after linking. for _, shader := range shaders { gl.DeleteShader(shader) } // Checking that it linked correctly. var linked int32 gl.GetProgramiv(program, gl.LINK_STATUS, &linked) if linked == gl.FALSE { var length int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &length) log := strings.Repeat("\x00", int(length+1)) gl.GetProgramInfoLog(program, length, nil, gl.Str(log)) return 0, errors.New("Shader program failed to link: " + log) } return ShaderProgram(program), nil }
func NewParticleSystem(position, direction glm.Vec3, size int) *ParticleSystem { ps := ParticleSystem{} ps.root = position ps.direction = direction ps.transformfeedbacks = gl2.GenTransformFeedbacks(2) MustNotGLError() ps.buffers = gl2.GenBuffers(2) MustNotGLError() ps.particles = make([]Particle, size) ps.isFirst = true ps.program = gl2.CreateProgram() vss, err := CompileShader(vs, gl2.VERTEX_SHADER) if err != nil { D(err) } ps.program.AttachShader(vss.Loc) gss, err := CompileShader(gs, gl2.GEOMETRY_SHADER) if err != nil { D(err) } ps.program.AttachShader(gss.Loc) fss, err := CompileShader(fs, gl2.FRAGMENT_SHADER) if err != nil { D(err) } ps.program.AttachShader(fss.Loc) ps.program.Link() if !ps.program.GetLinkStatus() { var logLength int32 gl.GetProgramiv(uint32(ps.program), gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(uint32(ps.program), logLength, nil, gl.Str(log)) } ps.gDeltaTimeMillis = ps.program.GetUniformLocation("gDeltaTimeMillis") ps.gTime = ps.program.GetUniformLocation("gTime") ps.gRandomTexture = ps.program.GetUniformLocation("gRandomTexture") ps.gLauncherLifetime = ps.program.GetUniformLocation("gLauncherLifetime") ps.gShellLifetime = ps.program.GetUniformLocation("gShellLifetime") ps.gSecondaryShellLifetime = ps.program.GetUniformLocation("gSecondaryShellLifetime") ps.particles[0].Lifetime = 0 ps.particles[0].Position = position ps.particles[0].Velocity = glm.Vec3{0, 0, 0} ps.particles[0].Type = Launcher for i := 0; i < len(ps.buffers); i++ { ps.transformfeedbacks[i].Bind() MustNotGLError() ps.buffers[i].Bind(gl2.ARRAY_BUFFER) MustNotGLError() ps.buffers[i].Data(gl2.ARRAY_BUFFER, int(unsafe.Sizeof(Particle{}))*len(ps.particles), unsafe.Pointer(&ps.particles[0]), gl2.DYNAMIC_DRAW) MustNotGLError() ps.transformfeedbacks[i].BindBufferBase(gl2.TRANSFORM_FEEDBACK_BUFFER, 0, ps.buffers[i]) MustNotGLError() } return &ps }
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 (p *Program) linkProgram(vertex uint32, fragment uint32) (program uint32, err error) { program = gl.CreateProgram() gl.AttachShader(program, vertex) gl.AttachShader(program, fragment) gl.BindFragDataLocation(program, 0, gl.Str("v_FragData\x00")) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR program.BindFragDataLocation %X", e) return } gl.LinkProgram(program) var status int32 if gl.GetProgramiv(program, gl.LINK_STATUS, &status); status == gl.FALSE { var length int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &length) log := strings.Repeat("\x00", int(length+1)) gl.GetProgramInfoLog(program, length, nil, gl.Str(log)) err = fmt.Errorf("ERROR program link:\n%s", log) } gl.DeleteShader(vertex) gl.DeleteShader(fragment) return }
func MakeProgram(vert, frag string) (uint32, error) { vertexShader, err := compileShader(vert, gl.VERTEX_SHADER) if err != nil { return 0, err } fragmentShader, err := compileShader(frag, 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) if ok := gl.GetError(); ok != gl.NO_ERROR { return 0, errors.New("Error in Make Program : " + string(ok)) } return program, 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 }