FontRenderer.cpp 3.1 KB

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