Пример #1
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,
	}
}
Пример #2
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
}