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.

TextureManager.cpp 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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. glm::vec2 TextureTile::getUV(unsigned int i) {
  24. glm::vec2 uv(vertices.at(i).xPixel,
  25. vertices.at(i).yPixel);
  26. /*! \fixme
  27. * This is my somewhat hacky approach to fixing
  28. * the bad texture-bleeding problems everywhere.
  29. * That's better, but makes the seams between
  30. * each sector much more visible!
  31. */
  32. if (vertices.at(i).xCoordinate == 1) {
  33. uv.x += 0.375f;
  34. }
  35. if (vertices.at(i).yCoordinate == 1) {
  36. uv.y += 0.375f;
  37. }
  38. return uv / 256.0f;
  39. }
  40. // ----------------------------------------------------------------------------
  41. TextureManager::~TextureManager() {
  42. while (mTextureIdsSystem.size() > 0) {
  43. unsigned int id = mTextureIdsSystem.at(mTextureIdsSystem.size() - 1);
  44. glDeleteTextures(1, &id);
  45. mTextureIdsSystem.pop_back();
  46. }
  47. clear();
  48. }
  49. void TextureManager::clear() {
  50. while (mTextureIdsGame.size() > 0) {
  51. unsigned int id = mTextureIdsGame.at(mTextureIdsGame.size() - 1);
  52. glDeleteTextures(1, &id);
  53. mTextureIdsGame.pop_back();
  54. }
  55. while (!tiles.empty()) {
  56. delete tiles.at(tiles.size() - 1);
  57. tiles.pop_back();
  58. }
  59. while (!animations.empty())
  60. animations.pop_back();
  61. }
  62. void TextureManager::addTile(TextureTile* t) {
  63. tiles.push_back(t);
  64. }
  65. int TextureManager::numTiles() {
  66. return tiles.size();
  67. }
  68. TextureTile& TextureManager::getTile(int index) {
  69. assert(index >= 0);
  70. assert(index < tiles.size());
  71. return *tiles.at(index);
  72. }
  73. void TextureManager::addAnimatedTile(int index, int tile) {
  74. while (index >= animations.size())
  75. animations.push_back(std::vector<int>());
  76. animations.at(index).push_back(tile);
  77. }
  78. int TextureManager::numAnimatedTiles() {
  79. return animations.size();
  80. }
  81. int TextureManager::getFirstTileAnimation(int index) {
  82. assert(index < animations.size());
  83. assert(animations.at(index).size() > 0);
  84. return animations.at(index).at(0);
  85. }
  86. int TextureManager::getNextTileAnimation(int tile) {
  87. for (int a = 0; a < animations.size(); a++) {
  88. for (int i = 0; i < animations.at(a).size(); i++) {
  89. if (animations.at(a).at(i) == tile) {
  90. if (i < (animations.at(a).size() - 1))
  91. return animations.at(a).at(i + 1);
  92. else
  93. return animations.at(a).at(0);
  94. }
  95. }
  96. }
  97. return -1;
  98. }
  99. std::vector<unsigned int>& TextureManager::getIds(TextureStorage s) {
  100. if (s == TextureStorage::GAME)
  101. return mTextureIdsGame;
  102. else
  103. return mTextureIdsSystem;
  104. }
  105. int TextureManager::initialize() {
  106. assert(mTextureIdsGame.size() == 0);
  107. assert(mTextureIdsSystem.size() == 0);
  108. while (mTextureIdsSystem.size() < 2) {
  109. unsigned int id;
  110. glGenTextures(1, &id);
  111. mTextureIdsSystem.push_back(id);
  112. }
  113. return 0;
  114. }
  115. int TextureManager::initializeSplash() {
  116. unsigned char* image = generateColorTexture(WHITE, 32, 32, 32);
  117. int res = loadBufferSlot(image, 32, 32, ColorMode::RGBA, 32, TextureStorage::SYSTEM, TEXTURE_WHITE,
  118. false);
  119. delete [] image;
  120. if (res < 0) {
  121. return -1;
  122. }
  123. //! \fixme Temporary?
  124. std::string filename = getRunTime().getPakDir() + "/tr2/TITLE.PCX";
  125. if (loadPCX(filename.c_str(), TextureStorage::SYSTEM, TEXTURE_SPLASH) < 0) {
  126. filename = getRunTime().getDataDir() + "/splash.tga";
  127. if (loadTGA(filename.c_str(), TextureStorage::SYSTEM, TEXTURE_SPLASH) < 0) {
  128. return -2;
  129. }
  130. }
  131. return 0;
  132. }
  133. int TextureManager::loadBufferSlot(unsigned char* image,
  134. unsigned int width, unsigned int height,
  135. ColorMode mode, unsigned int bpp,
  136. TextureStorage s, int slot, bool filter) {
  137. assert(width > 0);
  138. assert(height > 0);
  139. assert((mode == ColorMode::RGB)
  140. || (mode == ColorMode::BGR)
  141. || (mode == ColorMode::ARGB)
  142. || (mode == ColorMode::RGBA)
  143. || (mode == ColorMode::BGRA));
  144. assert((bpp == 8) || (bpp == 24) || (bpp == 32));
  145. if (slot == -1)
  146. slot = getIds(s).size();
  147. while (getIds(s).size() <= slot) {
  148. unsigned int id;
  149. glGenTextures(1, &id);
  150. getIds(s).push_back(id);
  151. }
  152. if (image == nullptr)
  153. return slot;
  154. unsigned int glcMode;
  155. switch (mode) {
  156. case ColorMode::BGR:
  157. glcMode = GL_BGR;
  158. break;
  159. case ColorMode::RGB:
  160. glcMode = GL_RGB;
  161. break;
  162. case ColorMode::ARGB:
  163. argb2rgba32(image, width, height);
  164. glcMode = GL_RGBA;
  165. break;
  166. case ColorMode::BGRA:
  167. glcMode = GL_BGRA;
  168. break;
  169. case ColorMode::RGBA:
  170. glcMode = GL_RGBA;
  171. break;
  172. }
  173. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  174. glBindTexture(GL_TEXTURE_2D, getIds(s).at(slot));
  175. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, glcMode, GL_UNSIGNED_BYTE, image);
  176. if (filter) {
  177. // Trilinear filtering
  178. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  179. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  180. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  181. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  182. glGenerateMipmap(GL_TEXTURE_2D);
  183. } else {
  184. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  185. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  186. }
  187. return slot;
  188. }
  189. int TextureManager::numTextures(TextureStorage s) {
  190. return getIds(s).size();
  191. }
  192. void TextureManager::bindTextureId(unsigned int n, TextureStorage s, unsigned int unit) {
  193. assert(n < getIds(s).size());
  194. assert(unit < 80); //! \todo Query GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
  195. glActiveTexture(GL_TEXTURE0 + unit);
  196. glBindTexture(GL_TEXTURE_2D, getIds(s).at(n));
  197. }
  198. int TextureManager::loadImage(const char* filename, TextureStorage s, int slot) {
  199. if (stringEndsWith(filename, ".pcx") || stringEndsWith(filename, ".PCX")) {
  200. return loadPCX(filename, s, slot);
  201. } else if (stringEndsWith(filename, ".png") || stringEndsWith(filename, ".PNG")) {
  202. return loadPNG(filename, s, slot);
  203. } else if (stringEndsWith(filename, ".tga") || stringEndsWith(filename, ".TGA")) {
  204. return loadTGA(filename, s, slot);
  205. } else {
  206. getLog() << "No known image file type? (" << filename << ")" << Log::endl;
  207. }
  208. return -1;
  209. }
  210. int TextureManager::loadPCX(const char* filename, TextureStorage s, int slot) {
  211. assert(filename != nullptr);
  212. assert(filename[0] != '\0');
  213. unsigned char* image;
  214. unsigned int w, h, bpp;
  215. ColorMode c;
  216. int id = -1;
  217. int error = pcxLoad(filename, &image, &w, &h, &c, &bpp);
  218. if (error == 0) {
  219. unsigned char* image2 = scaleBuffer(image, &w, &h, bpp);
  220. if (image2) {
  221. delete [] image;
  222. image = image2;
  223. }
  224. id = loadBufferSlot(image, w, h, c, bpp, s, slot);
  225. delete [] image;
  226. }
  227. return id;
  228. }
  229. int TextureManager::loadPNG(const char* filename, TextureStorage s, int slot) {
  230. #ifdef USING_PNG
  231. assert(filename != nullptr);
  232. assert(filename[0] != '\0');
  233. if (pngCheck(filename) != 0) {
  234. return -1;
  235. }
  236. unsigned char* image;
  237. unsigned int w, h, bpp;
  238. ColorMode c;
  239. int id = -1;
  240. int error = pngLoad(filename, &image, &w, &h, &c, &bpp);
  241. if (error == 0) {
  242. unsigned char* image2 = scaleBuffer(image, &w, &h, bpp);
  243. if (image2) {
  244. delete [] image;
  245. image = image2;
  246. }
  247. id = loadBufferSlot(image, w, h, c, bpp, s, slot);
  248. delete [] image;
  249. }
  250. return id;
  251. #else
  252. getLog() << "No PNG support available (" << filename << ")" << Log::endl;
  253. return -1;
  254. #endif
  255. }
  256. int TextureManager::loadTGA(const char* filename, TextureStorage s, int slot) {
  257. assert(filename != nullptr);
  258. assert(filename[0] != '\0');
  259. unsigned char* image;
  260. unsigned int w, h;
  261. char type;
  262. int id = -1;
  263. if (!tgaCheck(filename)) {
  264. tgaLoad(filename, &image, &w, &h, &type);
  265. unsigned char* image2 = scaleBuffer(image, &w, &h, (type == 2) ? 32 : 24);
  266. if (image2) {
  267. delete [] image;
  268. image = image2;
  269. }
  270. if (image) {
  271. id = loadBufferSlot(image, w, h,
  272. (type == 2) ? ColorMode::RGBA : ColorMode::RGB,
  273. (type == 2) ? 32 : 24,
  274. s, slot);
  275. delete [] image;
  276. }
  277. }
  278. return id;
  279. }