Beispiel #1
0
// 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
}
Beispiel #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,
	}
}
Beispiel #3
0
func dumpProgramError(program gl.Program, name string) error {
	str := gl.GetProgramInfoLog(program)
	msg := fmt.Sprintf("Program %s error:\n%s\n", name, str)
	dumpLog(msg)
	return errors.New(msg)
}