FontRenderer.cpp 3.1 KB

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