Open Source Tomb Raider Engine
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

TextureManager.cpp 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*!
  2. * \file src/TextureManager.cpp
  3. * \brief Texture registry
  4. *
  5. * \author Mongoose
  6. * \author xythobuz
  7. */
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #include "global.h"
  13. #include "Log.h"
  14. #include "RunTime.h"
  15. #include "utils/pcx.h"
  16. #include "utils/pixel.h"
  17. #include "utils/strings.h"
  18. #include "utils/tga.h"
  19. #include "TextureManager.h"
  20. #ifdef USING_PNG
  21. #include "utils/png.h"
  22. #endif
  23. std::vector<unsigned int>& TextureManager::getIds(TextureStorage s) {
  24. if (s == TextureStorage::GAME)
  25. return mTextureIdsGame;
  26. else
  27. return mTextureIdsSystem;
  28. }
  29. TextureManager::~TextureManager() {
  30. while (mTextureIdsSystem.size() > 0) {
  31. unsigned int id = mTextureIdsSystem.at(mTextureIdsSystem.size() - 1);
  32. glDeleteTextures(1, &id);
  33. mTextureIdsSystem.pop_back();
  34. }
  35. while (mTextureIdsGame.size() > 0) {
  36. unsigned int id = mTextureIdsGame.at(mTextureIdsGame.size() - 1);
  37. glDeleteTextures(1, &id);
  38. mTextureIdsGame.pop_back();
  39. }
  40. }
  41. int TextureManager::initialize() {
  42. unsigned char* image = generateColorTexture(WHITE, 32, 32, 32);
  43. int res = loadBufferSlot(image, 32, 32, RGBA, 32, TextureStorage::SYSTEM, TEXTURE_WHITE);
  44. delete [] image;
  45. if (res < 0) {
  46. return -1;
  47. }
  48. //! \fixme Temporary?
  49. std::string filename = getRunTime().getPakDir() + "/tr2/TITLE.PCX";
  50. if (loadPCX(filename.c_str(), TextureStorage::SYSTEM, TEXTURE_SPLASH) < 0) {
  51. filename = getRunTime().getDataDir() + "/splash.tga";
  52. if (loadTGA(filename.c_str(), TextureStorage::SYSTEM, TEXTURE_SPLASH) < 0) {
  53. return -2;
  54. }
  55. }
  56. return 0;
  57. }
  58. int TextureManager::loadBufferSlot(unsigned char* image,
  59. unsigned int width, unsigned int height,
  60. ColorMode mode, unsigned int bpp,
  61. TextureStorage s, int slot, bool filter) {
  62. assert(image != NULL);
  63. assert(width > 0);
  64. assert(height > 0);
  65. assert((mode == GREYSCALE) || (mode == RGB)
  66. || (mode == BGR) || (mode == ARGB)
  67. || (mode == RGBA) || (mode == BGRA));
  68. assert((bpp == 8) || (bpp == 24) || (bpp == 32));
  69. if (slot == -1)
  70. slot = getIds(s).size();
  71. while (getIds(s).size() <= slot) {
  72. unsigned int id;
  73. glGenTextures(1, &id);
  74. getIds(s).push_back(id);
  75. }
  76. unsigned int glcMode;
  77. switch (mode) {
  78. case GREYSCALE:
  79. glcMode = GL_LUMINANCE;
  80. break;
  81. case BGR:
  82. bgr2rgb24(image, width, height);
  83. glcMode = GL_RGB;
  84. break;
  85. case RGB:
  86. glcMode = GL_RGB;
  87. break;
  88. case ARGB:
  89. argb2rgba32(image, width, height);
  90. glcMode = GL_RGBA;
  91. break;
  92. case BGRA:
  93. bgra2rgba32(image, width, height);
  94. glcMode = GL_RGBA;
  95. break;
  96. case RGBA:
  97. glcMode = GL_RGBA;
  98. break;
  99. }
  100. glColor3ubv(WHITE);
  101. glEnable(GL_DEPTH_TEST);
  102. glShadeModel(GL_SMOOTH);
  103. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  104. glBindTexture(GL_TEXTURE_2D, getIds(s).at(slot));
  105. if (filter) {
  106. glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
  107. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  108. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  109. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  110. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  111. } else {
  112. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  113. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  114. }
  115. glTexImage2D(GL_TEXTURE_2D, 0, bpp / 8, width, height, 0, glcMode, GL_UNSIGNED_BYTE, image);
  116. return slot;
  117. }
  118. int TextureManager::numTextures(TextureStorage s) {
  119. return getIds(s).size();
  120. }
  121. void TextureManager::bindTextureId(unsigned int n, TextureStorage s) {
  122. assert(n < getIds(s).size());
  123. glEnable(GL_TEXTURE_2D);
  124. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  125. glBindTexture(GL_TEXTURE_2D, getIds(s).at(n));
  126. }
  127. int TextureManager::loadImage(const char* filename, TextureStorage s, int slot) {
  128. if (stringEndsWith(filename, ".pcx") || stringEndsWith(filename, ".PCX")) {
  129. return loadPCX(filename, s, slot);
  130. } else if (stringEndsWith(filename, ".png") || stringEndsWith(filename, ".PNG")) {
  131. return loadPNG(filename, s, slot);
  132. } else if (stringEndsWith(filename, ".tga") || stringEndsWith(filename, ".TGA")) {
  133. return loadTGA(filename, s, slot);
  134. } else {
  135. getLog() << "No known image file type? (" << filename << ")" << Log::endl;
  136. }
  137. return -1;
  138. }
  139. int TextureManager::loadPCX(const char* filename, TextureStorage s, int slot) {
  140. assert(filename != NULL);
  141. assert(filename[0] != '\0');
  142. unsigned char* image;
  143. unsigned int w, h, bpp;
  144. ColorMode c;
  145. int id = -1;
  146. int error = pcxLoad(filename, &image, &w, &h, &c, &bpp);
  147. if (error == 0) {
  148. unsigned char* image2 = scaleBuffer(image, &w, &h, bpp);
  149. if (image2) {
  150. delete [] image;
  151. image = image2;
  152. }
  153. id = loadBufferSlot(image, w, h, c, bpp, s, slot);
  154. delete [] image;
  155. }
  156. return id;
  157. }
  158. int TextureManager::loadPNG(const char* filename, TextureStorage s, int slot) {
  159. #ifdef USING_PNG
  160. assert(filename != NULL);
  161. assert(filename[0] != '\0');
  162. if (pngCheck(filename) != 0) {
  163. return -1;
  164. }
  165. unsigned char* image;
  166. unsigned int w, h, bpp;
  167. ColorMode c;
  168. int id = -1;
  169. int error = pngLoad(filename, &image, &w, &h, &c, &bpp);
  170. if (error == 0) {
  171. unsigned char* image2 = scaleBuffer(image, &w, &h, bpp);
  172. if (image2) {
  173. delete [] image;
  174. image = image2;
  175. }
  176. id = loadBufferSlot(image, w, h, c, bpp, s, slot);
  177. delete [] image;
  178. }
  179. return id;
  180. #else
  181. getLog() << "No PNG support available (" << filename << ")" << Log::endl;
  182. return -1;
  183. #endif
  184. }
  185. int TextureManager::loadTGA(const char* filename, TextureStorage s, int slot) {
  186. assert(filename != NULL);
  187. assert(filename[0] != '\0');
  188. unsigned char* image;
  189. unsigned int w, h;
  190. char type;
  191. int id = -1;
  192. if (!tgaCheck(filename)) {
  193. tgaLoad(filename, &image, &w, &h, &type);
  194. unsigned char* image2 = scaleBuffer(image, &w, &h, (type == 2) ? 32 : 24);
  195. if (image2) {
  196. delete [] image;
  197. image = image2;
  198. }
  199. if (image) {
  200. id = loadBufferSlot(image, w, h,
  201. (type == 2) ? RGBA : RGB,
  202. (type == 2) ? 32 : 24,
  203. s, slot);
  204. delete [] image;
  205. }
  206. }
  207. return id;
  208. }