A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

shaders.cc 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "shaders.h"
  2. namespace Cygnet::Shaders {
  3. const char *chunkVx = R"glsl(
  4. uniform mat3 camera;
  5. uniform vec2 pos;
  6. attribute vec2 vertex;
  7. varying vec2 v_tileCoord;
  8. void main() {
  9. vec3 pos = camera * vec3(pos + vertex, 1);
  10. gl_Position = vec4(pos.xy, 0, 1);
  11. v_tileCoord = vertex;
  12. }
  13. )glsl";
  14. const char *chunkFr = R"glsl(
  15. precision mediump float;
  16. #define TILE_SIZE 32.0
  17. #define CHUNK_WIDTH 64
  18. #define CHUNK_HEIGHT 64
  19. varying vec2 v_tileCoord;
  20. uniform sampler2D tileAtlas;
  21. uniform vec2 tileAtlasSize;
  22. uniform sampler2D tiles;
  23. void main() {
  24. vec2 tilePos = floor(vec2(v_tileCoord.x, v_tileCoord.y));
  25. vec4 tileColor = texture2D(tiles, tilePos / vec2(CHUNK_WIDTH, CHUNK_HEIGHT));
  26. float tileID = floor((tileColor.r * 256.0 + tileColor.a) * 256.0);
  27. // 1/(TILE_SIZE*16) plays the same role here as in the sprite vertex shader.
  28. vec2 offset = v_tileCoord - tilePos;
  29. vec2 pixoffset = (1.0 - offset * 2.0) / (TILE_SIZE * 16.0);
  30. vec2 atlasPos = vec2(
  31. pixoffset.x + tileID + offset.x,
  32. pixoffset.y + floor(tileID / tileAtlasSize.x) + offset.y);
  33. gl_FragColor = texture2D(tileAtlas, atlasPos / tileAtlasSize);
  34. }
  35. )glsl";
  36. const char *spriteVx = R"glsl(
  37. #define TILE_SIZE 32.0
  38. uniform mat3 camera;
  39. uniform mat3 transform;
  40. uniform vec2 frameSize;
  41. uniform vec2 frameInfo; // frame count, frame index
  42. attribute vec2 vertex;
  43. varying vec2 v_texCoord;
  44. void main() {
  45. // Here, I'm basically treating 1/(TILE_SIZE*16) as half the size of a "pixel".
  46. // It's just an arbitrary small number, but it works as an offset to make sure
  47. // neighbouring parts of the atlas don't bleed into the frame we actually
  48. // want to draw due to (nearest neighbour) interpolation.
  49. float pixoffset = (1.0 - vertex.y * 2.0) / (frameSize.y * TILE_SIZE * 16.0);
  50. v_texCoord = vec2(
  51. vertex.x,
  52. (frameSize.y * frameInfo.y + (frameSize.y * vertex.y)) /
  53. (frameSize.y * frameInfo.x) + pixoffset);
  54. vec3 pos = camera * transform * vec3(vertex * frameSize, 1);
  55. gl_Position = vec4(pos.xy, 0, 1);
  56. }
  57. )glsl";
  58. const char *spriteFr = R"glsl(
  59. precision mediump float;
  60. varying vec2 v_texCoord;
  61. uniform sampler2D tex;
  62. void main() {
  63. gl_FragColor = texture2D(tex, v_texCoord);
  64. }
  65. )glsl";
  66. const char *rectVx = R"glsl(
  67. uniform mat3 camera;
  68. uniform vec2 pos;
  69. uniform vec2 size;
  70. attribute vec2 vertex;
  71. varying vec2 v_coord;
  72. void main() {
  73. vec3 pos = camera * vec3(pos + vertex * size, 1);
  74. gl_Position = vec4(pos.xy, 0, 1);
  75. v_coord = vertex * size;
  76. }
  77. )glsl";
  78. const char *rectFr = R"glsl(
  79. precision mediump float;
  80. #define THICKNESS 0.02
  81. varying vec2 v_coord;
  82. uniform vec2 size;
  83. void main() {
  84. // TODO: This probably shouldn't be an if?
  85. if (
  86. v_coord.x < THICKNESS || v_coord.x > size.x - THICKNESS ||
  87. v_coord.y < THICKNESS || v_coord.y > size.y - THICKNESS) {
  88. gl_FragColor = vec4(0.6, 0.6, 0.6, 0.8);
  89. } else {
  90. gl_FragColor = vec4(0, 0, 0, 0);
  91. }
  92. }
  93. )glsl";
  94. }