func (c *glContext) stroke(call *glCall) { paths := c.paths[call.pathOffset : call.pathOffset+call.pathCount] if c.flags&StencilStrokes != 0 { gl.Enable(gl.STENCIL_TEST) c.setStencilMask(0xff) // Fill the stroke base without overlap c.setStencilFunc(gl.EQUAL, 0x00, 0xff) gl.StencilOp(gl.KEEP, gl.KEEP, gl.INCR) c.setUniforms(call.uniformOffset+1, call.image) checkError(c, "stroke fill 0") for i := range paths { path := &paths[i] gl.DrawArrays(gl.TRIANGLE_STRIP, path.strokeOffset, path.strokeCount) } // Draw anti-aliased pixels. c.setUniforms(call.uniformOffset, call.image) c.setStencilFunc(gl.EQUAL, 0x00, 0xff) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) for i := range paths { path := &paths[i] gl.DrawArrays(gl.TRIANGLE_STRIP, path.strokeOffset, path.strokeCount) } // Clear stencil buffer. gl.ColorMask(false, false, false, false) c.setStencilFunc(gl.ALWAYS, 0x00, 0xff) gl.StencilOp(gl.ZERO, gl.ZERO, gl.ZERO) checkError(c, "stroke fill 1") for i := range paths { path := &paths[i] gl.DrawArrays(gl.TRIANGLE_STRIP, path.strokeOffset, path.strokeCount) } gl.ColorMask(true, true, true, true) gl.Disable(gl.STENCIL_TEST) } else { c.setUniforms(call.uniformOffset, call.image) checkError(c, "stroke fill") for i := range paths { path := &paths[i] gl.DrawArrays(gl.TRIANGLE_STRIP, path.strokeOffset, path.strokeCount) } } }
func (c *glContext) convexFill(call *glCall) { paths := c.paths[call.pathOffset : call.pathOffset+call.pathCount] c.setUniforms(call.uniformOffset, call.image) checkError(c, "convex fill") for i := range paths { path := &paths[i] gl.DrawArrays(gl.TRIANGLE_FAN, path.fillOffset, path.fillCount) } if c.flags&AntiAlias != 0 { for i := range paths { path := &paths[i] gl.DrawArrays(gl.TRIANGLE_STRIP, path.strokeOffset, path.strokeCount) } } }
func (c *glContext) fill(call *glCall) { pathSentinel := call.pathOffset + call.pathCount // Draw shapes gl.Enable(gl.STENCIL_TEST) c.setStencilMask(0xff) c.setStencilFunc(gl.ALWAYS, 0x00, 0xff) gl.ColorMask(false, false, false, false) // set bindpoint for solid loc c.setUniforms(call.uniformOffset, 0) checkError(c, "fill simple") gl.StencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.INCR_WRAP) gl.StencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.DECR_WRAP) gl.Disable(gl.CULL_FACE) for i := call.pathOffset; i < pathSentinel; i++ { path := &c.paths[i] gl.DrawArrays(gl.TRIANGLE_FAN, path.fillOffset, path.fillCount) } gl.Enable(gl.CULL_FACE) // Draw anti-aliased pixels gl.ColorMask(true, true, true, true) c.setUniforms(call.uniformOffset+1, call.image) if c.flags&AntiAlias != 0 { c.setStencilFunc(gl.EQUAL, 0x00, 0xff) gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) // Draw fringes for i := call.pathOffset; i < pathSentinel; i++ { path := &c.paths[i] gl.DrawArrays(gl.TRIANGLE_STRIP, path.strokeOffset, path.strokeCount) } } // Draw fill c.setStencilFunc(gl.NOTEQUAL, 0x00, 0xff) gl.StencilOp(gl.ZERO, gl.ZERO, gl.ZERO) gl.DrawArrays(gl.TRIANGLES, call.triangleOffset, call.triangleCount) gl.Disable(gl.STENCIL_TEST) }
func (s shape) draw(ctx *context, shader *shaderProgram, ub uniformBindings) { shader.bind(ctx, s.vb, ub) if s.ib != nil { ctx.getOrCreateIndexBufferContext(s.ib).render(s.drawMode) } else { gl.DrawArrays(gl.Enum(s.drawMode), 0, s.vb.count) } shader.unbind(ctx) checkError() }
func (c *glContext) triangles(call *glCall) { c.setUniforms(call.uniformOffset, call.image) checkError(c, "triangles fill") gl.DrawArrays(gl.TRIANGLES, call.triangleOffset, call.triangleCount) }