t_shaders.nim 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import unittest
  2. import sigui, shady
  3. type ChessTiles = ref object of Uiobj
  4. tileSize: float
  5. registerComponent ChessTiles
  6. method draw*(this: ChessTiles, ctx: DrawContext) =
  7. this.drawBefore(ctx)
  8. if this.visibility == visible:
  9. let shader = ctx.makeShader:
  10. {.version: "300 es".}
  11. proc vert(
  12. gl_Position: var Vec4,
  13. pos: var Vec2,
  14. ipos: Vec2,
  15. transform: Uniform[Mat4],
  16. size: Uniform[Vec2],
  17. px: Uniform[Vec2],
  18. ) =
  19. # default sigui specific transformation to correct locate component on screen
  20. # and convert opengl's coordinate system (-1..1) to sigui's coordinate system (0..windowSize_inPixels)
  21. # out `pos` is component-local (0..componentSize_inPixels)
  22. transformation(gl_Position, pos, size.Vec2, px.Vec2, ipos, transform.Mat4)
  23. # don't use it if you don't need it (and don't call `ctx.passTransform` if so)
  24. proc frag(
  25. glCol: var Vec4,
  26. pos: Vec2,
  27. tileSize: Uniform[float],
  28. ) =
  29. if (
  30. (pos.x - ((pos.x / (tileSize * 2)).floor * (tileSize * 2)) >= tileSize) ==
  31. (pos.y - ((pos.y / (tileSize * 2)).floor * (tileSize * 2)) >= tileSize)
  32. ):
  33. glCol = vec4(1, 1, 1, 1)
  34. else:
  35. glCol = vec4(0, 0, 0, 1)
  36. glEnable(GlBlend)
  37. glBlendFuncSeparate(GlOne, GlOneMinusSrcAlpha, GlOne, GlOne)
  38. use shader.shader
  39. ctx.passTransform(shader, pos=(this.xy.posToGlobal(this.parent) + ctx.offset).round, size=this.wh.round, angle=0)
  40. shader.tileSize.uniform = this.tileSize
  41. draw ctx.rect
  42. glDisable(GlBlend)
  43. this.drawAfter(ctx)
  44. test "Custom shaders":
  45. preview(clearColor = color(0.5, 0.5, 0.5), margin = 20,
  46. withWindow = proc: Uiobj =
  47. let this = ChessTiles()
  48. init this
  49. this.bindingValue this.tileSize: min(this.w[] / 10, this.h[] / 10)
  50. this
  51. )