FontRenderer.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "client/rendering/FontRenderer.h"
  2. const size_t FontRenderer::BUFFER_LENGTH = 8 * 1024 * 1024;
  3. FontRenderer::FontRenderer() : tex("resources/font8x8.png"), offset(BUFFER_LENGTH), vba(0), vbo(0) {
  4. glGenVertexArrays(1, &vba);
  5. glBindVertexArray(vba);
  6. glGenBuffers(1, &vbo);
  7. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  8. glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof (float) * 7, static_cast<float*> (0));
  9. glEnableVertexAttribArray(0);
  10. glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof (float) * 7, static_cast<float*> (0) + 2);
  11. glEnableVertexAttribArray(1);
  12. glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof (float) * 7, static_cast<float*> (0) + 4);
  13. glEnableVertexAttribArray(2);
  14. }
  15. FontRenderer::~FontRenderer() {
  16. glDeleteVertexArrays(1, &vba);
  17. glDeleteBuffers(1, &vbo);
  18. }
  19. void FontRenderer::drawString(float x, float y, const char* text) {
  20. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  21. const size_t maxIndex = 256;
  22. const size_t maxLength = maxIndex * 4 * sizeof (float) * 7;
  23. if(offset + maxLength >= BUFFER_LENGTH) {
  24. offset = 0;
  25. glBufferData(GL_ARRAY_BUFFER, BUFFER_LENGTH, nullptr, GL_STREAM_DRAW);
  26. }
  27. float* buffer = static_cast<float*> (glMapBufferRange(GL_ARRAY_BUFFER, offset, maxLength, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT));
  28. if(buffer == nullptr) {
  29. return;
  30. }
  31. size_t index = 0;
  32. size_t i = 0;
  33. float r = 1.0f;
  34. float g = 1.0f;
  35. float b = 1.0f;
  36. while(text[index] != '\0' && index < maxIndex) {
  37. char c = text[index];
  38. if(c == '&') {
  39. if(text[index + 1] == '\0' || text[index + 2] == '\0' || text[index + 3] == '\0') {
  40. break;
  41. }
  42. r = (text[index + 1] - '0') * (1.0f / 9.0f);
  43. g = (text[index + 2] - '0') * (1.0f / 9.0f);
  44. b = (text[index + 3] - '0') * (1.0f / 9.0f);
  45. index += 4;
  46. continue;
  47. }
  48. float minX = (c & 0xF) * (1.0f / 16.0f);
  49. float minY = (c >> 4) * (1.0f / 16.0f);
  50. float maxX = minX + (1.0f / 16.0f);
  51. float maxY = minY + (1.0f / 16.0f);
  52. buffer[i++] = x;
  53. buffer[i++] = y;
  54. buffer[i++] = minX;
  55. buffer[i++] = minY;
  56. buffer[i++] = r;
  57. buffer[i++] = g;
  58. buffer[i++] = b;
  59. buffer[i++] = x;
  60. buffer[i++] = y + 8;
  61. buffer[i++] = minX;
  62. buffer[i++] = maxY;
  63. buffer[i++] = r;
  64. buffer[i++] = g;
  65. buffer[i++] = b;
  66. buffer[i++] = x + 8;
  67. buffer[i++] = y;
  68. buffer[i++] = maxX;
  69. buffer[i++] = minY;
  70. buffer[i++] = r;
  71. buffer[i++] = g;
  72. buffer[i++] = b;
  73. buffer[i++] = x + 8;
  74. buffer[i++] = y + 8;
  75. buffer[i++] = maxX;
  76. buffer[i++] = maxY;
  77. buffer[i++] = r;
  78. buffer[i++] = g;
  79. buffer[i++] = b;
  80. x += 8;
  81. index++;
  82. }
  83. glUnmapBuffer(GL_ARRAY_BUFFER);
  84. glBindVertexArray(vba);
  85. tex.bind(0);
  86. glDrawArrays(GL_TRIANGLE_STRIP, offset / (sizeof (float) * 7), i / 7);
  87. offset += maxLength;
  88. }