示例#1
0
文件: glutil.go 项目: shibukawa/gl
// CreateProgram creates, compiles, and links a gl.Program.
func CreateProgram(vertexSrc, fragmentSrc string) (gl.Program, error) {
	program := gl.CreateProgram()
	if !program.Valid() {
		return gl.Program{}, fmt.Errorf("glutil: no programs available")
	}

	vertexShader, err := loadShader(gl.VERTEX_SHADER, vertexSrc)
	if err != nil {
		return gl.Program{}, err
	}
	fragmentShader, err := loadShader(gl.FRAGMENT_SHADER, fragmentSrc)
	if err != nil {
		gl.DeleteShader(vertexShader)
		return gl.Program{}, err
	}

	gl.AttachShader(program, vertexShader)
	gl.AttachShader(program, fragmentShader)
	gl.LinkProgram(program)

	// Flag shaders for deletion when program is unlinked.
	gl.DeleteShader(vertexShader)
	gl.DeleteShader(fragmentShader)

	if gl.GetProgrami(program, gl.LINK_STATUS) == 0 {
		defer gl.DeleteProgram(program)
		return gl.Program{}, fmt.Errorf("glutil: %s", gl.GetProgramInfoLog(program))
	}
	return program, nil
}
示例#2
0
func newShaderProgram(ctx *context, vsSource, fsSource string) *shaderProgram {
	vs := compile(vsSource, gl.VERTEX_SHADER)
	fs := compile(fsSource, gl.FRAGMENT_SHADER)

	program := gl.CreateProgram()
	gl.AttachShader(program, vs)
	gl.AttachShader(program, fs)
	gl.LinkProgram(program)

	if gl.GetProgrami(program, gl.LINK_STATUS) != gl.TRUE {
		panic(gl.GetProgramInfoLog(program))
	}

	gl.UseProgram(program)
	checkError()

	uniformCount := gl.GetProgrami(program, gl.ACTIVE_UNIFORMS)
	uniforms := make([]shaderUniform, uniformCount)
	textureUnit := 0
	for i := range uniforms {
		name, size, ty := gl.GetActiveUniform(program, uint32(i))
		location := gl.GetUniformLocation(program, name)
		uniforms[i] = shaderUniform{
			name:        name,
			size:        size,
			ty:          shaderDataType(ty),
			location:    location,
			textureUnit: textureUnit,
		}
		if ty == gl.SAMPLER_2D {
			textureUnit++
		}
	}

	attributeCount := gl.GetProgrami(program, gl.ACTIVE_ATTRIBUTES)
	attributes := make([]shaderAttribute, attributeCount)
	for i := range attributes {
		name, size, ty := gl.GetActiveAttrib(program, uint32(i))
		location := gl.GetAttribLocation(program, name)
		attributes[i] = shaderAttribute{
			name:     name,
			size:     size,
			ty:       shaderDataType(ty),
			location: location,
		}
	}

	ctx.stats.shaderProgramCount++

	return &shaderProgram{
		program:    program,
		uniforms:   uniforms,
		attributes: attributes,
	}
}
示例#3
0
func (s *glShader) createShader(name, header, opts, vShader, fShader string) error {
	program := gl.CreateProgram()

	vertexShader := gl.CreateShader(gl.VERTEX_SHADER)
	gl.ShaderSource(vertexShader, strings.Join([]string{header, opts, vShader}, "\n"))
	gl.CompileShader(vertexShader)
	status := gl.Enum(gl.GetShaderi(vertexShader, gl.COMPILE_STATUS))
	if status != gl.TRUE {
		return dumpShaderError(vertexShader, name, "vert")
	}

	fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER)
	gl.ShaderSource(fragmentShader, strings.Join([]string{header, opts, fShader}, "\n"))
	gl.CompileShader(fragmentShader)
	status = gl.Enum(gl.GetShaderi(fragmentShader, gl.COMPILE_STATUS))
	if status != gl.TRUE {
		return dumpShaderError(fragmentShader, name, "vert")
	}

	gl.AttachShader(program, vertexShader)
	gl.AttachShader(program, fragmentShader)

	gl.LinkProgram(program)
	status = gl.Enum(gl.GetProgrami(program, gl.LINK_STATUS))
	if status != gl.TRUE {
		return dumpProgramError(program, name)
	}

	s.vertexAttrib = gl.GetAttribLocation(program, "vertex")
	s.tcoordAttrib = gl.GetAttribLocation(program, "tcoord")

	s.program = program
	s.vertex = vertexShader
	s.fragment = fragmentShader

	return nil
}