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 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. TextureTileVertex::TextureTileVertex(uint8_t xc, uint8_t xp, uint8_t yc, uint8_t yp)
  24. : xCoordinate(xc), xPixel(xp), yCoordinate(yc), yPixel(yp) { }
  25. // ----------------------------------------------------------------------------
  26. TextureTile::~TextureTile() {
  27. while (!vertices.empty()) {
  28. delete vertices.at(vertices.size() - 1);
  29. vertices.pop_back();
  30. }
  31. }
  32. void TextureTile::add(TextureTileVertex* t) {
  33. vertices.push_back(t);
  34. }
  35. void TextureTile::displayRectangle(float x, float y, float w, float h, float z) {
  36. assert(vertices.size() == 4);
  37. getTextureManager().bindTextureId(texture);
  38. //glBegin(GL_TRIANGLE_STRIP);
  39. glBegin(GL_QUADS);
  40. for (int i = 0; i < 4; i++) {
  41. glTexCoord2f(vertices.at(i)->xPixel / 256.0f,
  42. vertices.at(i)->yPixel / 256.0f);
  43. if (vertices.at(i)->xCoordinate == 255) {
  44. if (vertices.at(i)->yCoordinate == 255) {
  45. glVertex3f(x + w, y + h, z);
  46. } else {
  47. glVertex3f(x + w, y, z);
  48. }
  49. } else {
  50. if (vertices.at(i)->yCoordinate == 255) {
  51. glVertex3f(x, y + h, z);
  52. } else {
  53. glVertex3f(x, y, z);
  54. }
  55. }
  56. }
  57. glEnd();
  58. }
  59. // ----------------------------------------------------------------------------
  60. TextureManager::~TextureManager() {
  61. while (mTextureIdsSystem.size() > 0) {
  62. unsigned int id = mTextureIdsSystem.at(mTextureIdsSystem.size() - 1);
  63. glDeleteTextures(1, &id);
  64. mTextureIdsSystem.pop_back();
  65. }
  66. while (mTextureIdsGame.size() > 0) {
  67. unsigned int id = mTextureIdsGame.at(mTextureIdsGame.size() - 1);
  68. glDeleteTextures(1, &id);
  69. mTextureIdsGame.pop_back();
  70. }
  71. while (!tiles.empty()) {
  72. delete tiles.at(tiles.size() - 1);
  73. tiles.pop_back();
  74. }
  75. }
  76. void TextureManager::addTile(TextureTile* t) {
  77. tiles.push_back(t);
  78. }
  79. int TextureManager::numTiles() {
  80. return tiles.size();
  81. }
  82. TextureTile& TextureManager::getTile(int index) {
  83. assert(index >= 0);
  84. assert(index < tiles.size());
  85. return *tiles.at(index);
  86. }
  87. std::vector<unsigned int>& TextureManager::getIds(TextureStorage s) {
  88. if (s == TextureStorage::GAME)
  89. return mTextureIdsGame;
  90. else
  91. return mTextureIdsSystem;
  92. }
  93. int TextureManager::initialize() {
  94. unsigned char* image = generateColorTexture(WHITE, 32, 32, 32);
  95. int res = loadBufferSlot(image, 32, 32, RGBA, 32, TextureStorage::SYSTEM, TEXTURE_WHITE);
  96. delete [] image;
  97. if (res < 0) {
  98. return -1;
  99. }
  100. //! \fixme Temporary?
  101. std::string filename = getRunTime().getPakDir() + "/tr2/TITLE.PCX";
  102. if (loadPCX(filename.c_str(), TextureStorage::SYSTEM, TEXTURE_SPLASH) < 0) {
  103. filename = getRunTime().getDataDir() + "/splash.tga";
  104. if (loadTGA(filename.c_str(), TextureStorage::SYSTEM, TEXTURE_SPLASH) < 0) {
  105. return -2;
  106. }
  107. }
  108. return 0;
  109. }
  110. int TextureManager::loadBufferSlot(unsigned char* image,
  111. unsigned int width, unsigned int height,
  112. ColorMode mode, unsigned int bpp,
  113. TextureStorage s, int slot, bool filter) {
  114. assert(image != NULL);
  115. assert(width > 0);
  116. assert(height > 0);
  117. assert((mode == GREYSCALE) || (mode == RGB)
  118. || (mode == BGR) || (mode == ARGB)
  119. || (mode == RGBA) || (mode == BGRA));
  120. assert((bpp == 8) || (bpp == 24) || (bpp == 32));
  121. if (slot == -1)
  122. slot = getIds(s).size();
  123. while (getIds(s).size() <= slot) {
  124. unsigned int id;
  125. glGenTextures(1, &id);
  126. getIds(s).push_back(id);
  127. }
  128. unsigned int glcMode;
  129. switch (mode) {
  130. case GREYSCALE:
  131. glcMode = GL_LUMINANCE;
  132. break;
  133. case BGR:
  134. bgr2rgb24(image, width, height);
  135. glcMode = GL_RGB;
  136. break;
  137. case RGB:
  138. glcMode = GL_RGB;
  139. break;
  140. case ARGB:
  141. argb2rgba32(image, width, height);
  142. glcMode = GL_RGBA;
  143. break;
  144. case BGRA:
  145. bgra2rgba32(image, width, height);
  146. glcMode = GL_RGBA;
  147. break;
  148. case RGBA:
  149. glcMode = GL_RGBA;
  150. break;
  151. }
  152. glColor3ubv(WHITE);
  153. glEnable(GL_DEPTH_TEST);
  154. glShadeModel(GL_SMOOTH);
  155. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  156. glBindTexture(GL_TEXTURE_2D, getIds(s).at(slot));
  157. if (filter) {
  158. glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
  159. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  160. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  161. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  162. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  163. } else {
  164. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  165. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  166. }
  167. glTexImage2D(GL_TEXTURE_2D, 0, bpp / 8, width, height, 0, glcMode, GL_UNSIGNED_BYTE, image);
  168. return slot;
  169. }
  170. int TextureManager::numTextures(TextureStorage s) {
  171. return getIds(s).size();
  172. }
  173. void TextureManager::bindTextureId(unsigned int n, TextureStorage s) {
  174. assert(n < getIds(s).size());
  175. glEnable(GL_TEXTURE_2D);
  176. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  177. glBindTexture(GL_TEXTURE_2D, getIds(s).at(n));
  178. }
  179. int TextureManager::loadImage(const char* filename, TextureStorage s, int slot) {
  180. if (stringEndsWith(filename, ".pcx") || stringEndsWith(filename, ".PCX")) {
  181. return loadPCX(filename, s, slot);
  182. } else if (stringEndsWith(filename, ".png") || stringEndsWith(filename, ".PNG")) {
  183. return loadPNG(filename, s, slot);
  184. } else if (stringEndsWith(filename, ".tga") || stringEndsWith(filename, ".TGA")) {
  185. return loadTGA(filename, s, slot);
  186. } else {
  187. getLog() << "No known image file type? (" << filename << ")" << Log::endl;
  188. }
  189. return -1;
  190. }
  191. int TextureManager::loadPCX(const char* filename, TextureStorage s, int slot) {
  192. assert(filename != NULL);
  193. assert(filename[0] != '\0');
  194. unsigned char* image;
  195. unsigned int w, h, bpp;
  196. ColorMode c;
  197. int id = -1;
  198. int error = pcxLoad(filename, &image, &w, &h, &c, &bpp);
  199. if (error == 0) {
  200. unsigned char* image2 = scaleBuffer(image, &w, &h, bpp);
  201. if (image2) {
  202. delete [] image;
  203. image = image2;
  204. }
  205. id = loadBufferSlot(image, w, h, c, bpp, s, slot);
  206. delete [] image;
  207. }
  208. return id;
  209. }
  210. int TextureManager::loadPNG(const char* filename, TextureStorage s, int slot) {
  211. #ifdef USING_PNG
  212. assert(filename != NULL);
  213. assert(filename[0] != '\0');
  214. if (pngCheck(filename) != 0) {
  215. return -1;
  216. }
  217. unsigned char* image;
  218. unsigned int w, h, bpp;
  219. ColorMode c;
  220. int id = -1;
  221. int error = pngLoad(filename, &image, &w, &h, &c, &bpp);
  222. if (error == 0) {
  223. unsigned char* image2 = scaleBuffer(image, &w, &h, bpp);
  224. if (image2) {
  225. delete [] image;
  226. image = image2;
  227. }
  228. id = loadBufferSlot(image, w, h, c, bpp, s, slot);
  229. delete [] image;
  230. }
  231. return id;
  232. #else
  233. getLog() << "No PNG support available (" << filename << ")" << Log::endl;
  234. return -1;
  235. #endif
  236. }
  237. int TextureManager::loadTGA(const char* filename, TextureStorage s, int slot) {
  238. assert(filename != NULL);
  239. assert(filename[0] != '\0');
  240. unsigned char* image;
  241. unsigned int w, h;
  242. char type;
  243. int id = -1;
  244. if (!tgaCheck(filename)) {
  245. tgaLoad(filename, &image, &w, &h, &type);
  246. unsigned char* image2 = scaleBuffer(image, &w, &h, (type == 2) ? 32 : 24);
  247. if (image2) {
  248. delete [] image;
  249. image = image2;
  250. }
  251. if (image) {
  252. id = loadBufferSlot(image, w, h,
  253. (type == 2) ? RGBA : RGB,
  254. (type == 2) ? 32 : 24,
  255. s, slot);
  256. delete [] image;
  257. }
  258. }
  259. return id;
  260. }