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 }
// 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 NewProgram(shaderSource map[string]string) (*GLSLProgram, error) { var hasVertexShader bool var hasFragmentShader bool vertexShaderSource, ok := shaderSource["vertex"] var vertexShader uint32 if ok { vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { return nil, err } hasVertexShader = true } fragmentShaderSource, ok := shaderSource["fragment"] var fragmentShader uint32 if ok { fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { return nil, err } hasFragmentShader = true } program := gl.CreateProgram() if !(hasVertexShader && hasFragmentShader) { return nil, fmt.Errorf("Need vertex shader: %v, and fragment shader: %v", hasVertexShader, hasFragmentShader) } 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 nil, fmt.Errorf("Failed to link program(%v): %v", program, log) } gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) p := &GLSLProgram{program, vertexShaderSource, fragmentShaderSource, true} return p, nil }
func LoadShaders(shaders []ShaderInfo) (uint32, error) { program := gl.CreateProgram() for _, shaderInfo := range shaders { shader, err := shaderInfo.CompileShader() if err != nil { return 0, err } gl.AttachShader(program, shader) gl.DeleteShader(shader) } 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) } return program, nil }
func newProgram(shaders ...uint32) (uint32, error) { program := gl.CreateProgram() for _, shader := range shaders { gl.AttachShader(program, shader) } 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)) } for _, shader := range shaders { gl.DeleteShader(shader) } return program, nil }
func newProgram(vertexShaderFilename, fragmentShaderFilename string) (uint32, error) { program := gl.CreateProgram() //vertexShaderSource, err := shaders.Asset(vertexShaderFilename) //if err != nil { // return 0, err //} vertexShader, err := shaders.Compile(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { return 0, err } //fragmentShaderSource, err := shaders.Asset(fragmentShaderFilename) //if err != nil { // return 0, err //} fragmentShader, err := shaders.Compile(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { return 0, err } 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 (me *Core) AddProgram(vertFile, fragFile string) int { vertexShader := gl.Str(readWholeFile(vertFile) + "\x00") fragmentShader := gl.Str(readWholeFile(fragFile) + "\x00") n := me.nbProg vs := gl.CreateShader(gl.VERTEX_SHADER) gl.ShaderSource(vs, 1, &vertexShader, nil) gl.CompileShader(vs) fs := gl.CreateShader(gl.FRAGMENT_SHADER) gl.ShaderSource(fs, 1, &fragmentShader, nil) gl.CompileShader(fs) me.Progs[n] = gl.CreateProgram() gl.AttachShader(me.Progs[n], fs) gl.AttachShader(me.Progs[n], vs) gl.LinkProgram(me.Progs[n]) // Will be deleteted when Detach shader are called gl.DeleteShader(vs) gl.DeleteShader(fs) me.nbProg++ return n }
/* * Link the provided shaders in the order they were given and return the linked program. */ func linkShaders(shaders []uint32) uint32 { program := gl.CreateProgram() for _, shader := range shaders { gl.AttachShader(program, shader) } gl.LinkProgram(program) checkProgramLinkErrors(program) // shader objects are not needed after they are linked into a program object for _, shader := range shaders { gl.DeleteShader(shader) } return program }
func (shader *Shader) Delete() { gl.DeleteShader(shader.handle) }
func programLoop(window *glfw.Window) { // the linked shader program determines how the data will be rendered vertexShader := compileShader(vertexShaderSource, gl.VERTEX_SHADER) fragmentShaderBlue := compileShader(fragmentShaderBlueSource, gl.FRAGMENT_SHADER) shaderProgramBlue := linkShaders([]uint32{vertexShader, fragmentShaderBlue}) fragmentShaderRed := compileShader(fragmentShaderRedSource, gl.FRAGMENT_SHADER) shaderProgramRed := linkShaders([]uint32{vertexShader, fragmentShaderRed}) // shader objects are not needed after they are linked into a program object gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShaderBlue) gl.DeleteShader(fragmentShaderRed) vertices1 := []float32{ 0.2, 0.2, 0.0, // top right 0.2, -0.8, 0.0, // bottom right -0.8, -0.8, 0.0, // bottom left -0.8, 0.2, 0.0, // top left } indices1 := []uint32{ 0, 1, 3, // first triangle 1, 2, 3, // second triangle } VAO1 := createTriangleVAO(vertices1, indices1) vertices2 := []float32{ 0.2, 0.6, 0.0, // top 0.6, -0.2, 0.0, // bottom right -0.2, -0.2, 0.0, // bottom left } indices2 := []uint32{ 0, 1, 2, // only triangle } VAO2 := createTriangleVAO(vertices2, indices2) for !window.ShouldClose() { // poll events and call their registered callbacks glfw.PollEvents() // perform rendering gl.ClearColor(0.2, 0.5, 0.5, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT) // draw loop // draw rectangle gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) gl.UseProgram(shaderProgramRed) gl.BindVertexArray(VAO1) gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, unsafe.Pointer(nil)) gl.BindVertexArray(0) // draw triangle gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) gl.UseProgram(shaderProgramBlue) gl.BindVertexArray(VAO2) gl.DrawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, unsafe.Pointer(nil)) gl.BindVertexArray(0) // end of draw loop // swap in the rendered buffer window.SwapBuffers() } }