shaderPanel.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package shader
  5. func init() {
  6. AddShader("shaderPanelVertex", shaderPanelVertex)
  7. AddShader("shaderPanelFrag", shaderPanelFrag)
  8. AddProgram("shaderPanel", "shaderPanelVertex", "shaderPanelFrag")
  9. }
  10. //
  11. // Vertex Shader template
  12. //
  13. const shaderPanelVertex = `
  14. #version {{.Version}}
  15. // Vertex attributes
  16. {{template "attributes" .}}
  17. // Input uniforms
  18. uniform mat4 ModelMatrix;
  19. // Outputs for fragment shader
  20. out vec2 FragTexcoord;
  21. void main() {
  22. // Always flip texture coordinates
  23. vec2 texcoord = VertexTexcoord;
  24. texcoord.y = 1 - texcoord.y;
  25. FragTexcoord = texcoord;
  26. // Set position
  27. vec4 pos = vec4(VertexPosition.xyz, 1);
  28. gl_Position = ModelMatrix * pos;
  29. }
  30. `
  31. //
  32. // Fragment Shader template
  33. //
  34. const shaderPanelFrag = `
  35. #version {{.Version}}
  36. // Textures uniforms
  37. uniform sampler2D MatTexture[1];
  38. uniform mat3 MatTexinfo[1];
  39. // Macros to access elements inside MatTexinfo uniform
  40. #define MatTexOffset(a) MatTexinfo[a][0].xy
  41. #define MatTexRepeat(a) MatTexinfo[a][1].xy
  42. #define MatTexFlipY(a) bool(MatTexinfo[a][2].x)
  43. #define MatTexVisible(a) bool(MatTexinfo[a][2].y)
  44. // Inputs from vertex shader
  45. in vec2 FragTexcoord;
  46. // Input uniform
  47. uniform vec4 Panel[8];
  48. #define Bounds Panel[0] // panel bounds in texture coordinates
  49. #define Border Panel[1] // panel border in texture coordinates
  50. #define Padding Panel[2] // panel padding in texture coordinates
  51. #define Content Panel[3] // panel content area in texture coordinates
  52. #define BorderColor Panel[4] // panel border color
  53. #define PaddingColor Panel[5] // panel padding color
  54. #define ContentColor Panel[6] // panel content color
  55. #define TextureValid bool(Panel[7].x) // texture valid flag
  56. // Output
  57. out vec4 FragColor;
  58. /***
  59. * Checks if current fragment texture coordinate is inside the
  60. * supplied rectangle in texture coordinates:
  61. * rect[0] - position x [0,1]
  62. * rect[1] - position y [0,1]
  63. * rect[2] - width [0,1]
  64. * rect[3] - height [0,1]
  65. */
  66. bool checkRect(vec4 rect) {
  67. if (FragTexcoord.x < rect[0]) {
  68. return false;
  69. }
  70. if (FragTexcoord.x > rect[0] + rect[2]) {
  71. return false;
  72. }
  73. if (FragTexcoord.y < rect[1]) {
  74. return false;
  75. }
  76. if (FragTexcoord.y > rect[1] + rect[3]) {
  77. return false;
  78. }
  79. return true;
  80. }
  81. void main() {
  82. // Discard fragment outside of received bounds
  83. // Bounds[0] - xmin
  84. // Bounds[1] - ymin
  85. // Bounds[2] - xmax
  86. // Bounds[3] - ymax
  87. if (FragTexcoord.x <= Bounds[0] || FragTexcoord.x >= Bounds[2]) {
  88. discard;
  89. }
  90. if (FragTexcoord.y <= Bounds[1] || FragTexcoord.y >= Bounds[3]) {
  91. discard;
  92. }
  93. // Check if fragment is inside content area
  94. if (checkRect(Content)) {
  95. // If no texture, the color will be the material color.
  96. vec4 color = ContentColor;
  97. if (TextureValid) {
  98. // Adjust texture coordinates to fit texture inside the content area
  99. vec2 offset = vec2(-Content[0], -Content[1]);
  100. vec2 factor = vec2(1/Content[2], 1/Content[3]);
  101. vec2 texcoord = (FragTexcoord + offset) * factor;
  102. color = texture(MatTexture[0], texcoord * MatTexRepeat(0) + MatTexOffset(0));
  103. }
  104. if (color.a == 0) {
  105. discard;
  106. }
  107. FragColor = color;
  108. return;
  109. }
  110. // Checks if fragment is inside paddings area
  111. if (checkRect(Padding)) {
  112. FragColor = PaddingColor;
  113. return;
  114. }
  115. // Checks if fragment is inside borders area
  116. if (checkRect(Border)) {
  117. FragColor = BorderColor;
  118. return;
  119. }
  120. // Fragment is in margins area (always transparent)
  121. FragColor = vec4(1,1,1,0);
  122. }
  123. `