Beispiel #1
0
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
}
Beispiel #2
0
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, &param)
	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, &param)
	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, &param)
	if param == 0 {
		return fmt.Errorf("Failed to link shader '%s': %v", name, param)
	}

	shader_progs[name] = program_id
	return nil
}
Beispiel #3
0
// 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
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
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
}
Beispiel #7
0
// 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
}