Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

GLString.cpp 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /*!
  2. * \file src/GLString.cpp
  3. * \brief Open GL rendering font/string class
  4. *
  5. * \author Mongoose
  6. */
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <stdarg.h>
  11. #ifdef __APPLE__
  12. #include <OpenGL/gl.h>
  13. #else
  14. #include <GL/gl.h>
  15. #endif
  16. #include <Texture.h>
  17. #include <GLString.h>
  18. #ifdef DEBUG_MEMORY
  19. #include <memory_test.h>
  20. #endif
  21. GLString::GLString()
  22. {
  23. _num_string_max = 0;
  24. _num_font_max = 0;
  25. _num_font = 0;
  26. _num_string = 0;
  27. _scale = 1.0;
  28. _font_texture = NULL;
  29. _font_base = NULL;
  30. _string = NULL;
  31. }
  32. GLString::~GLString()
  33. {
  34. unsigned int i;
  35. for (i = 0; i < _num_font; ++i)
  36. {
  37. glDeleteLists(_font_base[i], 256);
  38. }
  39. if (_font_texture)
  40. {
  41. delete [] _font_texture;
  42. }
  43. if (_font_base)
  44. {
  45. delete [] _font_base;
  46. }
  47. if (_string)
  48. {
  49. for (i = 0; i < _num_string; ++i)
  50. {
  51. if (_string[i].text)
  52. {
  53. delete [] _string[i].text;
  54. }
  55. }
  56. delete [] _string;
  57. }
  58. }
  59. void GLString::Init(unsigned int max_strings, unsigned int max_fonts,
  60. int *tex_map)
  61. {
  62. unsigned int i;
  63. if (!max_strings || !max_fonts || !tex_map)
  64. {
  65. return;
  66. }
  67. _num_string_max = max_strings;
  68. _num_font_max = max_fonts;
  69. _font_texture = new int[max_fonts];
  70. _font_base = new int[max_fonts];
  71. _string = new gl_string_t[max_strings];
  72. for (i = 0; i < max_fonts; ++i)
  73. {
  74. _font_texture[i] = tex_map[i];
  75. if (BuildFontList(i) < 0)
  76. {
  77. printf("GLString::Init> BuildFontList failed for %i\n", i);
  78. }
  79. }
  80. }
  81. void GLString::SetChar(unsigned int string, unsigned int pos, char c)
  82. {
  83. gl_string_t *str = GetString(string);
  84. if (str && pos < str->len)
  85. {
  86. str->text[pos] = c;
  87. }
  88. }
  89. unsigned int GLString::GetStringLen(unsigned int string)
  90. {
  91. gl_string_t *str = GetString(string);
  92. if (str)
  93. {
  94. return str->len;
  95. }
  96. return 0;
  97. }
  98. char *GLString::GetBuffer(unsigned int string)
  99. {
  100. gl_string_t *str = GetString(string);
  101. if (str)
  102. {
  103. return str->text;
  104. }
  105. return 0;
  106. }
  107. void GLString::setActive(unsigned int string, bool active)
  108. {
  109. gl_string_t *str;
  110. str = GetString(string);
  111. if (str)
  112. {
  113. str->active = active;
  114. }
  115. }
  116. void GLString::SetString(unsigned int string, const char *s, ...)
  117. {
  118. va_list args;
  119. gl_string_t *str;
  120. unsigned int len;
  121. str = GetString(string);
  122. if (s && s[0] && str)
  123. {
  124. str->active = true;
  125. len = strlen(s);
  126. if (len > str->len)
  127. {
  128. len = str->len - 1;
  129. }
  130. va_start(args, s);
  131. vsnprintf(str->text, str->len-2, s, args);
  132. str->text[str->len-1] = 0;
  133. va_end(args);
  134. }
  135. }
  136. void GLString::Scale(float scale)
  137. {
  138. _scale = scale;
  139. }
  140. int GLString::BuildFontList(int index)
  141. {
  142. int i;
  143. float cx;
  144. float cy;
  145. if (_num_font >= _num_font_max || index < 0 || index >= (int)_num_font_max)
  146. {
  147. return -1;
  148. }
  149. _font_base[index] = glGenLists(256);
  150. glBindTexture(GL_TEXTURE_2D, _font_texture[index]);
  151. // Mongoose 2002.01.01, Generate 256 lists per font
  152. // one per symbol
  153. for (i = 0; i < 256; i++)
  154. {
  155. /* X Position Of Current Character */
  156. cx = 1 - (float)(i % 16) / 16.0f;
  157. /* Y Position Of Current Character */
  158. cy = 1 - (float)(i / 16) / 16.0f;
  159. /* Start Building A List */
  160. glNewList(_font_base[index] + (255 - i), GL_COMPILE);
  161. /* Use A Quad For Each Character */
  162. glBegin(GL_QUADS);
  163. /* Texture Coord (Bottom Left) */
  164. glTexCoord2f(cx - 0.0625, cy);
  165. /* Vertex Coord (Bottom Left) */
  166. glVertex2i(0, 0);
  167. /* Texture Coord (Bottom Right) */
  168. glTexCoord2f(cx, cy);
  169. /* Vertex Coord (Bottom Right) */
  170. glVertex2i(16, 0);
  171. /* Texture Coord (Top Right) */
  172. glTexCoord2f(cx, cy - 0.0625f);
  173. /* Vertex Coord (Top Right) */
  174. glVertex2i(16, 16);
  175. /* Texture Coord (Top Left) */
  176. glTexCoord2f(cx - 0.0625f, cy - 0.0625f);
  177. /* Vertex Coord (Top Left) */
  178. glVertex2i(0, 16);
  179. glEnd();
  180. /* Move To The Left Of The Character */
  181. glTranslated(10, 0, 0);
  182. glEndList();
  183. }
  184. return 0;
  185. }
  186. int GLString::glPrintf(int x, int y, int font, const char *string, ...)
  187. {
  188. int sz = 60;
  189. int n;
  190. va_list args;
  191. // Mongoose 2002.01.01, Only allow valid strings
  192. // we must assume it's NULL terminated also if it passes...
  193. if (!string || !string[0])
  194. {
  195. return -1;
  196. }
  197. if (_num_string > _num_string_max)
  198. {
  199. return -2;
  200. }
  201. if (font < 0 || font > (int)_num_font_max)
  202. {
  203. return -3;
  204. }
  205. // Mongoose 2002.01.01, Assume no longer than 'sz' wide lines
  206. // on first try
  207. _string[_num_string].text = new char[sz];
  208. // Mongoose 2002.01.03, Setup scale factor
  209. _string[_num_string].scale = _scale;
  210. // Mongoose 2002.01.01, Setup position
  211. _string[_num_string].x = x;
  212. _string[_num_string].y = y;
  213. // Mongoose 2002.01.01, Setup font list base index to use
  214. _string[_num_string].font = font;
  215. va_start(args, string);
  216. // Mongoose 2002.01.01, Get exact size needed if the first try fails
  217. n = vsnprintf(_string[_num_string].text, sz, string, args);
  218. // Mongoose 2002.01.01, Realloc correct amount if truncated
  219. while (1)
  220. {
  221. if (n > -1 && n < sz)
  222. {
  223. break;
  224. }
  225. // Mongoose 2002.01.01, For glibc 2.1
  226. if (n > -1)
  227. {
  228. sz = n + 1;
  229. delete [] _string[_num_string].text;
  230. _string[_num_string].text = new char[sz];
  231. n = vsnprintf(_string[_num_string].text, sz, string, args);
  232. break;
  233. }
  234. else // glibc 2.0
  235. {
  236. sz *= 2;
  237. delete [] _string[_num_string].text;
  238. _string[_num_string].text = new char[sz];
  239. n = vsnprintf(_string[_num_string].text, sz, string, args);
  240. }
  241. }
  242. va_end(args);
  243. // Mongoose 2002.01.04, Remeber string size, for future rebuffering use
  244. _string[_num_string].len = sz;
  245. // Mongoose 2002.01.01, Incement string counter, since we just
  246. // allocated a string
  247. ++_num_string;
  248. return 0;
  249. }
  250. void GLString::Render(int width, int height)
  251. {
  252. unsigned int i;
  253. #ifndef HAVE_SDL_TTF
  254. // Mongoose 2001.12.31, Start the evil font rendering...
  255. glLoadIdentity();
  256. glDisable(GL_DEPTH_TEST);
  257. // Mongoose 2001.12.31, New 'flat' projection
  258. glMatrixMode(GL_PROJECTION);
  259. glPushMatrix();
  260. glLoadIdentity();
  261. glOrtho(0, width, 0, height, -1, 1);
  262. // Mongoose 2001.12.31, New rendering matrix
  263. glMatrixMode(GL_MODELVIEW);
  264. glPushMatrix();
  265. glLoadIdentity();
  266. // Mongoose 2001.12.31, Rasterize strings' text
  267. for (i = 0; i < _num_string; ++i)
  268. {
  269. if (_string[i].active)
  270. {
  271. glPushMatrix();
  272. glBindTexture(GL_TEXTURE_2D, _font_texture[_string[i].font]);
  273. glTranslated(_string[i].x, _string[i].y, 0);
  274. glScaled(_string[i].scale, _string[i].scale, _string[i].scale);
  275. glListBase(_font_base[_string[i].font] - 32);
  276. glCallLists(strlen(_string[i].text), GL_BYTE, _string[i].text);
  277. glPopMatrix();
  278. }
  279. }
  280. // Mongoose 2001.12.31, Restore scene projection
  281. glMatrixMode(GL_PROJECTION);
  282. glPopMatrix();
  283. // Mongoose 2001.12.31, Restore scene matrix
  284. glMatrixMode(GL_MODELVIEW);
  285. glPopMatrix();
  286. glEnable(GL_DEPTH_TEST);
  287. #else
  288. for (i = 0; i < _num_string; ++i)
  289. {
  290. if (_string[i].active)
  291. {
  292. glPrint2d(_string[i].x, _string[i].y,
  293. _string[i].scale,
  294. _string[i].text);
  295. }
  296. }
  297. #endif
  298. }
  299. gl_string_t *GLString::GetString(unsigned int id)
  300. {
  301. if (id < _num_string)
  302. {
  303. return _string + id;
  304. }
  305. return NULL;
  306. }