tile_glyph.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #ifndef TILE_GLYPH_H
  2. #define TILE_GLYPH_H
  3. #include "glyph_attr.h"
  4. struct tile_glyph {
  5. struct vec2i tile;
  6. int32_t c;
  7. struct vec4f fg_color;
  8. struct vec4f bg_color;
  9. };
  10. DA_DEF_STRUCT(struct tile_glyph, tile_glyph_da);
  11. enum tile_glyph_attr_enum {
  12. TILE_GLYPH_ATTR_TILE = 0,
  13. TILE_GLYPH_ATTR_C,
  14. TILE_GLYPH_ATTR_FG_COLOR,
  15. TILE_GLYPH_ATTR_BG_COLOR,
  16. TILE_GLYPH_ATTR_TOTAL
  17. };
  18. struct ret_uint32_t_uint32_t {
  19. uint32_t f1;
  20. uint32_t f2;
  21. };
  22. struct tile_glyph_da tile_glyph_da_create(void);
  23. const struct glyph_attr* tile_glyph_get_attrs(void);
  24. struct tile_glyph_da tile_glyph_da_calc(struct app app,
  25. struct tile_glyph_da glys,
  26. const char *cstr, size_t cstr_size,
  27. struct vec2i tile,
  28. struct vec4f fg_color,
  29. struct vec4f bg_color);
  30. struct tile_glyph_da tile_glyph_da_calc_buffer(struct app app,
  31. struct tile_glyph_da glys,
  32. struct vec2i tile);
  33. void tile_glyph_da_sync(struct app app, struct tile_glyph_da glys);
  34. uint32_t tile_glyph_gen_buffer(struct tile_glyph_da glys);
  35. uint32_t tile_glyph_load_texture_atlas(const char *filepath);
  36. struct ret_uint32_t_uint32_t tile_glyph_compile_shaders_or_exit(void);
  37. #if defined(TILE_GLYPH_IMP) || defined(IMP)
  38. #ifdef STB_IMAGE_IMPLEMENTATION
  39. #undef STB_IMAGE_IMPLEMENTATION
  40. #include "stb_image.h"
  41. #define STB_IMAGE_IMPLEMENTATION
  42. #else
  43. #include "stb_image.h"
  44. #endif
  45. #include "unwrap.h"
  46. struct tile_glyph_da
  47. tile_glyph_da_create(void)
  48. {
  49. struct tile_glyph_da glys;
  50. glys.cap = 1024 * 1024;
  51. glys.size = 0;
  52. glys.items = calloc(glys.cap, sizeof(struct tile_glyph));
  53. return glys;
  54. }
  55. const struct glyph_attr *
  56. tile_glyph_get_attrs(void)
  57. {
  58. static const struct glyph_attr
  59. tile_glyph_attr[TILE_GLYPH_ATTR_TOTAL] = {
  60. [TILE_GLYPH_ATTR_TILE] = {
  61. .size = 2,
  62. .type = GL_INT,
  63. .norm = GL_FALSE,
  64. .stride = sizeof(struct tile_glyph),
  65. .offset = offsetof(struct tile_glyph, tile)
  66. },
  67. [TILE_GLYPH_ATTR_C] = {
  68. .size = 1,
  69. .type = GL_INT,
  70. .norm = GL_FALSE,
  71. .stride = sizeof(struct tile_glyph),
  72. .offset = offsetof(struct tile_glyph, c)
  73. },
  74. [TILE_GLYPH_ATTR_FG_COLOR] = {
  75. .size = 4,
  76. .type = GL_FLOAT,
  77. .norm = GL_FALSE,
  78. .stride = sizeof(struct tile_glyph),
  79. .offset = offsetof(struct tile_glyph, fg_color)
  80. },
  81. [TILE_GLYPH_ATTR_BG_COLOR] = {
  82. .size = 4,
  83. .type = GL_FLOAT,
  84. .norm = GL_FALSE,
  85. .stride = sizeof(struct tile_glyph),
  86. .offset = offsetof(struct tile_glyph, bg_color)
  87. },
  88. };
  89. return tile_glyph_attr;
  90. }
  91. struct tile_glyph_da
  92. tile_glyph_da_calc(struct app app, struct tile_glyph_da glys,
  93. const char *cstr, size_t cstr_size, struct vec2i tile,
  94. struct vec4f fg_color, struct vec4f bg_color)
  95. {
  96. (void) app;
  97. struct vec2i pen = tile;
  98. int32_t row = 0;
  99. for ( size_t i = 0; i < cstr_size; ++i ) {
  100. char c = cstr[i];
  101. if ( c == '\n' ) {
  102. pen.y -= 1;
  103. row = 0;
  104. continue;
  105. }
  106. struct tile_glyph gly = {
  107. .tile = vec2i_add(pen, vec2i(row, 0)),
  108. .c = c,
  109. .fg_color = fg_color,
  110. .bg_color = bg_color
  111. };
  112. DA_APPEND(glys, gly);
  113. ++row;
  114. }
  115. return glys;
  116. }
  117. struct tile_glyph_da
  118. tile_glyph_da_calc_buffer(struct app app, struct tile_glyph_da glys,
  119. struct vec2i tile)
  120. {
  121. return tile_glyph_da_calc(app, glys,
  122. app.buf.data.items, app.buf.data.size,
  123. tile, vec4fs(1), vec4fs(0));
  124. }
  125. void
  126. tile_glyph_da_sync(struct app app, struct tile_glyph_da glys)
  127. {
  128. (void) app;
  129. glBufferSubData(GL_ARRAY_BUFFER, 0,
  130. (ssize_t) (glys.size * sizeof(struct tile_glyph)),
  131. glys.items);
  132. }
  133. uint32_t
  134. tile_glyph_gen_buffer(struct tile_glyph_da glys)
  135. {
  136. uint32_t id = 0;
  137. glGenBuffers(1, &id);
  138. glBindBuffer(GL_ARRAY_BUFFER, id);
  139. glBufferData(GL_ARRAY_BUFFER,
  140. (ssize_t)(glys.cap * sizeof(struct tile_glyph)),
  141. glys.items,
  142. GL_DYNAMIC_DRAW);
  143. glyph_attr_declare(tile_glyph_get_attrs(), TILE_GLYPH_ATTR_TOTAL);
  144. return id;
  145. }
  146. uint32_t
  147. tile_glyph_load_texture_atlas(const char *filepath)
  148. {
  149. uint32_t id;
  150. int32_t w, h, n;
  151. uint8_t *data = stbi_load(filepath,
  152. &w, &h, &n,
  153. STBI_rgb_alpha);
  154. if ( data == NULL ) {
  155. fprintf(stderr, "ERROR loading file %s: %s",
  156. filepath, stbi_failure_reason());
  157. exit(EXIT_FAILURE);
  158. }
  159. glActiveTexture(GL_TEXTURE0);
  160. glGenTextures(1, &id);
  161. glBindTexture(GL_TEXTURE_2D, id);
  162. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  163. GL_NEAREST);
  164. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  165. GL_NEAREST);
  166. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
  167. GL_CLAMP_TO_EDGE);
  168. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
  169. GL_CLAMP_TO_EDGE);
  170. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h,
  171. 0, GL_RGBA, GL_UNSIGNED_BYTE,
  172. data);
  173. return id;
  174. }
  175. struct ret_uint32_t_uint32_t
  176. tile_glyph_compile_shaders_or_exit(void)
  177. {
  178. return (struct ret_uint32_t_uint32_t) {
  179. .f1 = shader_compile_file_or_exit("./shaders/tile_font.vert",
  180. GL_VERTEX_SHADER),
  181. .f2 = shader_compile_file_or_exit("./shaders/tile_font.frag",
  182. GL_FRAGMENT_SHADER),
  183. };
  184. }
  185. #endif /* defined(TILE_GLYPH_IMP) || defined(IMP) */
  186. #endif