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] }
func (u *shaderUniform) bind(context *context, v interface{}) { switch u.ty { case stFloatMat2: gl.UniformMatrix2fv(u.location, v.([]float32)) case stFloatMat3: switch m := v.(type) { case math.Mat3: gl.UniformMatrix3fv(u.location, m[:]) case []float32: gl.UniformMatrix3fv(u.location, m) } case stFloatMat4: gl.UniformMatrix4fv(u.location, v.([]float32)) case stFloatVec1: switch v := v.(type) { case float32: gl.Uniform1f(u.location, v) case []float32: gl.Uniform1fv(u.location, v) } case stFloatVec2: switch v := v.(type) { case math.Vec2: gl.Uniform2fv(u.location, []float32{v.X, v.Y}) case []float32: if len(v)%2 != 0 { panic(fmt.Errorf("Uniform '%s' of type vec2 should be an float32 array with a multiple of two length", u.name)) } gl.Uniform2fv(u.location, v) } case stFloatVec3: switch v := v.(type) { case math.Vec3: gl.Uniform3fv(u.location, []float32{v.X, v.Y, v.Z}) case []float32: if len(v)%3 != 0 { panic(fmt.Errorf("Uniform '%s' of type vec3 should be an float32 array with a multiple of three length", u.name)) } gl.Uniform3fv(u.location, v) } case stFloatVec4: switch v := v.(type) { case math.Vec4: gl.Uniform4fv(u.location, []float32{v.X, v.Y, v.Z, v.W}) case gxui.Color: gl.Uniform4fv(u.location, []float32{v.R, v.G, v.B, v.A}) case []float32: if len(v)%4 != 0 { panic(fmt.Errorf("Uniform '%s' of type vec4 should be an float32 array with a multiple of four length", u.name)) } gl.Uniform4fv(u.location, v) } case stSampler2d: tc := v.(*textureContext) gl.ActiveTexture(gl.Enum(gl.TEXTURE0 + u.textureUnit)) gl.BindTexture(gl.TEXTURE_2D, tc.texture) gl.Uniform1i(u.location, u.textureUnit) default: panic(fmt.Errorf("Uniform of unsupported type %s", u.ty)) } }