Exemple #1
0
func (s *shaderProgram) bind(ctx *context, vb *vertexBuffer, uniforms uniformBindings) {
	gl.UseProgram(s.program)
	for _, a := range s.attributes {
		vs, found := vb.streams[a.name]
		if !found {
			panic(fmt.Errorf("VertexBuffer missing required stream '%s'", a.name))
		}
		if a.ty != vs.ty {
			panic(fmt.Errorf("Attribute '%s' type '%s' does not match stream type '%s'",
				a.name, a.ty, vs.ty))
		}
		elementCount := a.ty.vectorElementCount()
		elementTy := a.ty.vectorElementType()
		ctx.getOrCreateVertexStreamContext(vs).bind()
		a.enableArray()
		a.attribPointer(int32(elementCount), uint32(elementTy), false, 0, 0)
	}
	for _, u := range s.uniforms {
		v, found := uniforms[u.name]
		if !found {
			panic(fmt.Errorf("Uniforms missing '%s'", u.name))
		}
		u.bind(ctx, v)
	}
	checkError()
}
Exemple #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,
	}
}
Exemple #3
0
func (p *glParams) renderFlush() {
	c := p.context

	if len(c.calls) > 0 {
		gl.UseProgram(c.shader.program)

		gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
		gl.Enable(gl.CULL_FACE)
		gl.CullFace(gl.BACK)
		gl.FrontFace(gl.CCW)
		gl.Enable(gl.BLEND)
		gl.Disable(gl.DEPTH_TEST)
		gl.Disable(gl.SCISSOR_TEST)
		gl.ColorMask(true, true, true, true)
		gl.StencilMask(0xffffffff)
		gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)
		gl.StencilFunc(gl.ALWAYS, 0, 0xffffffff)
		gl.ActiveTexture(gl.TEXTURE0)
		gl.BindTexture(gl.TEXTURE_2D, gl.Texture{})
		c.stencilMask = 0xffffffff
		c.stencilFunc = gl.ALWAYS
		c.stencilFuncRef = 0
		c.stencilFuncMask = 0xffffffff

		b := castFloat32ToByte(c.vertexes)
		//dumpLog("vertex:", c.vertexes)
		// Upload vertex data
		gl.BindBuffer(gl.ARRAY_BUFFER, c.vertexBuffer)
		gl.BufferData(gl.ARRAY_BUFFER, b, gl.STREAM_DRAW)
		gl.EnableVertexAttribArray(c.shader.vertexAttrib)
		gl.EnableVertexAttribArray(c.shader.tcoordAttrib)
		gl.VertexAttribPointer(c.shader.vertexAttrib, 2, gl.FLOAT, false, 4*4, 0)
		gl.VertexAttribPointer(c.shader.tcoordAttrib, 2, gl.FLOAT, false, 4*4, 8)

		// Set view and texture just once per frame.
		gl.Uniform1i(c.shader.locations[glnvgLocTEX], 0)
		gl.Uniform2fv(c.shader.locations[glnvgLocVIEWSIZE], c.view[:])

		for i := range c.calls {
			call := &c.calls[i]
			switch call.callType {
			case glnvgFILL:
				c.fill(call)
			case glnvgCONVEXFILL:
				c.convexFill(call)
			case glnvgSTROKE:
				c.stroke(call)
			case glnvgTRIANGLES:
				c.triangles(call)
			}
		}
		gl.DisableVertexAttribArray(c.shader.vertexAttrib)
		gl.DisableVertexAttribArray(c.shader.tcoordAttrib)
		gl.Disable(gl.CULL_FACE)
		gl.BindBuffer(gl.ARRAY_BUFFER, gl.Buffer{})
		gl.UseProgram(gl.Program{})
		c.bindTexture(nil)
	}
	c.vertexes = c.vertexes[:0]
	c.paths = c.paths[:0]
	c.calls = c.calls[:0]
	c.uniforms = c.uniforms[:0]
}