Open Source Tomb Raider Engine
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.

FontSDL.cpp 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*!
  2. * \file src/system/FontSDL.cpp
  3. * \brief SDL Font implementation
  4. *
  5. * \author xythobuz
  6. */
  7. #include <iostream>
  8. #include "global.h"
  9. #include "TextureManager.h"
  10. #include "system/Shader.h"
  11. #include "system/FontSDL.h"
  12. bool FontSDL::mFontInit = false;
  13. TTF_Font* FontSDL::mFont = nullptr;
  14. unsigned int FontSDL::mFontTexture = -1;
  15. ShaderBuffer FontSDL::vertexBuffer;
  16. ShaderBuffer FontSDL::uvBuffer;
  17. void FontSDL::shutdown() {
  18. if (mFont != nullptr)
  19. TTF_CloseFont(mFont);
  20. mFont = nullptr;
  21. if (mFontInit) {
  22. TTF_Quit();
  23. mFontInit = false;
  24. }
  25. }
  26. int FontSDL::initialize(std::string font) {
  27. if (!mFontInit) {
  28. if (TTF_Init() != 0) {
  29. std::cout << "Could not initialize SDL-TTF!" << std::endl;
  30. return -1;
  31. }
  32. // Reserve slot
  33. mFontTexture = TextureManager::loadBufferSlot(nullptr, 256, 256,
  34. ColorMode::RGBA, 32,
  35. TextureStorage::SYSTEM);
  36. mFontInit = true;
  37. }
  38. if (mFont != nullptr)
  39. TTF_CloseFont(mFont);
  40. mFont = TTF_OpenFont(font.c_str(), 24);
  41. if (mFont == nullptr) {
  42. std::cout << "TTF_OpenFont Error: " << TTF_GetError() << std::endl;
  43. return -2;
  44. }
  45. return 0;
  46. }
  47. unsigned int FontSDL::widthText(float scale, std::string s) {
  48. assert(mFontInit == true);
  49. assert(mFont != nullptr);
  50. int w;
  51. if (TTF_SizeUTF8(mFont, s.c_str(), &w, nullptr) != 0) {
  52. std::cout << "TTF_SizeUTF8 Error: " << TTF_GetError() << std::endl;
  53. return s.length() * 15 * scale;
  54. }
  55. return w * scale;
  56. }
  57. void FontSDL::drawText(unsigned int x, unsigned int y, float scale,
  58. const unsigned char color[4], std::string s) {
  59. assert(mFontInit == true);
  60. assert(mFont != nullptr);
  61. assert(s.length() > 0);
  62. SDL_Color col;
  63. col.r = color[0];
  64. col.g = color[1];
  65. col.b = color[2];
  66. col.a = color[3];
  67. SDL_Surface* surface = TTF_RenderUTF8_Blended(mFont, s.c_str(), col);
  68. if (surface == nullptr) {
  69. std::cout << "TTF_RenderUTF8_Blended Error: " << TTF_GetError() << std::endl;
  70. return;
  71. }
  72. int w = (int)((float)surface->w * scale);
  73. int h = (int)((float)surface->h * scale);
  74. ColorMode textureFormat;
  75. unsigned int bpp = 0;
  76. if (surface->format->BytesPerPixel == 4) {
  77. if (surface->format->Rmask == 0x000000FF)
  78. textureFormat = ColorMode::RGBA;
  79. else
  80. textureFormat = ColorMode::BGRA;
  81. bpp = 32;
  82. } else {
  83. if (surface->format->Rmask == 0x000000FF)
  84. textureFormat = ColorMode::RGB;
  85. else
  86. textureFormat = ColorMode::BGR;
  87. bpp = 24;
  88. }
  89. TextureManager::loadBufferSlot(static_cast<unsigned char*>(surface->pixels),
  90. surface->w, surface->h, textureFormat, bpp,
  91. TextureStorage::SYSTEM, mFontTexture);
  92. SDL_FreeSurface(surface);
  93. std::vector<glm::vec2> vertices;
  94. std::vector<glm::vec2> uvs;
  95. vertices.push_back(glm::vec2(x, y + h));
  96. vertices.push_back(glm::vec2(x, y));
  97. vertices.push_back(glm::vec2(x + w, y + h));
  98. vertices.push_back(glm::vec2(x + w, y));
  99. vertices.push_back(glm::vec2(x + w, y + h));
  100. vertices.push_back(glm::vec2(x, y));
  101. uvs.push_back(glm::vec2(0.0f, 1.0f));
  102. uvs.push_back(glm::vec2(0.0f, 0.0f));
  103. uvs.push_back(glm::vec2(1.0f, 1.0f));
  104. uvs.push_back(glm::vec2(1.0f, 0.0f));
  105. uvs.push_back(glm::vec2(1.0f, 1.0f));
  106. uvs.push_back(glm::vec2(0.0f, 0.0f));
  107. vertexBuffer.bufferData(vertices);
  108. uvBuffer.bufferData(uvs);
  109. Shader::drawGL(vertexBuffer, uvBuffer, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f),
  110. mFontTexture, TextureStorage::SYSTEM);
  111. }
  112. unsigned int FontSDL::heightText(float scale, unsigned int maxWidth, std::string s) {
  113. assert(mFontInit == true);
  114. assert(mFont != nullptr);
  115. assert(s.length() > 0);
  116. assert(maxWidth > 0);
  117. SDL_Color col;
  118. SDL_Surface* surface = TTF_RenderUTF8_Blended_Wrapped(mFont, s.c_str(), col, maxWidth);
  119. if (surface == nullptr) {
  120. std::cout << "TTF_RenderUTF8_Blended_Wrapped Error: " << TTF_GetError() << std::endl;
  121. return 0;
  122. }
  123. int h = surface->h * scale;
  124. SDL_FreeSurface(surface);
  125. return h;
  126. }
  127. void FontSDL::drawTextWrapped(unsigned int x, unsigned int y, float scale,
  128. const unsigned char color[4], unsigned int maxWidth, std::string s) {
  129. assert(mFontInit == true);
  130. assert(mFont != nullptr);
  131. assert(s.length() > 0);
  132. assert(maxWidth > 0);
  133. SDL_Color col;
  134. col.r = color[0];
  135. col.g = color[1];
  136. col.b = color[2];
  137. col.a = color[3];
  138. SDL_Surface* surface = TTF_RenderUTF8_Blended_Wrapped(mFont, s.c_str(), col, maxWidth);
  139. if (surface == nullptr) {
  140. std::cout << "TTF_RenderUTF8_Blended_Wrapped Error: " << TTF_GetError() << std::endl;
  141. return;
  142. }
  143. int w = (int)((float)surface->w * scale);
  144. int h = (int)((float)surface->h * scale);
  145. ColorMode textureFormat;
  146. unsigned int bpp = 0;
  147. if (surface->format->BytesPerPixel == 4) {
  148. if (surface->format->Rmask == 0x000000FF)
  149. textureFormat = ColorMode::RGBA;
  150. else
  151. textureFormat = ColorMode::BGRA;
  152. bpp = 32;
  153. } else {
  154. if (surface->format->Rmask == 0x000000FF)
  155. textureFormat = ColorMode::RGB;
  156. else
  157. textureFormat = ColorMode::BGR;
  158. bpp = 24;
  159. }
  160. TextureManager::loadBufferSlot(static_cast<unsigned char*>(surface->pixels),
  161. surface->w, surface->h, textureFormat, bpp,
  162. TextureStorage::SYSTEM, mFontTexture);
  163. SDL_FreeSurface(surface);
  164. std::vector<glm::vec2> vertices;
  165. std::vector<glm::vec2> uvs;
  166. vertices.push_back(glm::vec2(x, y + h));
  167. vertices.push_back(glm::vec2(x, y));
  168. vertices.push_back(glm::vec2(x + w, y + h));
  169. vertices.push_back(glm::vec2(x + w, y));
  170. vertices.push_back(glm::vec2(x + w, y + h));
  171. vertices.push_back(glm::vec2(x, y));
  172. uvs.push_back(glm::vec2(0.0f, 1.0f));
  173. uvs.push_back(glm::vec2(0.0f, 0.0f));
  174. uvs.push_back(glm::vec2(1.0f, 1.0f));
  175. uvs.push_back(glm::vec2(1.0f, 0.0f));
  176. uvs.push_back(glm::vec2(1.0f, 1.0f));
  177. uvs.push_back(glm::vec2(0.0f, 0.0f));
  178. vertexBuffer.bufferData(vertices);
  179. uvBuffer.bufferData(uvs);
  180. Shader::drawGL(vertexBuffer, uvBuffer, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f),
  181. mFontTexture, TextureStorage::SYSTEM);
  182. }