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.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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 "utils/pcx.h"
  14. #include "utils/pixel.h"
  15. #include "utils/strings.h"
  16. #include "utils/tga.h"
  17. #include "TextureManager.h"
  18. TextureManager::TextureManager() {
  19. mTextureIds = NULL;
  20. mFlags = 0;
  21. mTextureCount = 0;
  22. mTextureLimit = 0;
  23. }
  24. TextureManager::~TextureManager() {
  25. reset();
  26. }
  27. unsigned char *TextureManager::generateColorTexture(unsigned char rgba[4],
  28. unsigned int width, unsigned int height) {
  29. assert(rgba != NULL);
  30. assert(width > 0);
  31. assert(height > 0);
  32. unsigned char *image = new unsigned char[height * width * 4];
  33. for (unsigned int i = 0; i < (width * height); i++) {
  34. image[i * 4] = rgba[0];
  35. image[(i * 4) + 1] = rgba[1];
  36. image[(i * 4) + 2] = rgba[2];
  37. image[(i * 4) + 3] = rgba[3];
  38. }
  39. return image;
  40. }
  41. int TextureManager::loadColorTexture(unsigned char rgba[4],
  42. unsigned int width, unsigned int height) {
  43. assert(rgba != NULL);
  44. assert(width > 0);
  45. assert(height > 0);
  46. unsigned char *image = generateColorTexture(rgba, width, height);
  47. int id = loadBuffer(image, width, height, RGBA, 32);
  48. delete [] image;
  49. return id;
  50. }
  51. void TextureManager::setFlag(TextureFlag flag) {
  52. mFlags |= flag;
  53. }
  54. void TextureManager::clearFlag(TextureFlag flag) {
  55. mFlags &= ~flag;
  56. }
  57. void TextureManager::reset() {
  58. if (mTextureIds) {
  59. glDeleteTextures(mTextureLimit, mTextureIds);
  60. delete [] mTextureIds;
  61. }
  62. mTextureIds = NULL;
  63. mTextureCount = 0;
  64. mTextureLimit = 0;
  65. }
  66. void TextureManager::disableMultiTexture() {
  67. mFlags &= ~fUseMultiTexture;
  68. glDisable(GL_TEXTURE_2D);
  69. glActiveTextureARB(GL_TEXTURE0_ARB);
  70. }
  71. void TextureManager::useMultiTexture(float aU, float aV, float bU, float bV) {
  72. if (!(mFlags & fUseMultiTexture))
  73. return;
  74. glMultiTexCoord2fARB(GL_TEXTURE0_ARB, aU, aV);
  75. glMultiTexCoord2fARB(GL_TEXTURE1_ARB, bU, bV);
  76. }
  77. void TextureManager::useMultiTexture(float u, float v) {
  78. useMultiTexture(u, v, u, v);
  79. }
  80. void TextureManager::bindMultiTexture(int texture0, int texture1) {
  81. assert(mTextureIds != NULL);
  82. assert(texture0 >= 0);
  83. assert(texture1 >= 0);
  84. assert((unsigned int)texture0 <= mTextureCount);
  85. assert((unsigned int)texture1 <= mTextureCount);
  86. mFlags |= fUseMultiTexture;
  87. glActiveTextureARB(GL_TEXTURE0_ARB);
  88. glEnable(GL_TEXTURE_2D);
  89. glBindTexture(GL_TEXTURE_2D, mTextureIds[texture0]);
  90. glActiveTextureARB(GL_TEXTURE1_ARB);
  91. glEnable(GL_TEXTURE_2D);
  92. glBindTexture(GL_TEXTURE_2D, mTextureIds[texture1]);
  93. }
  94. void TextureManager::setMaxTextureCount(unsigned int n) {
  95. mTextureLimit = n;
  96. mTextureIds = new unsigned int[n];
  97. glGenTextures(n, mTextureIds);
  98. }
  99. int TextureManager::getTextureCount() {
  100. return mTextureCount - 1;
  101. }
  102. int TextureManager::loadBuffer(unsigned char *image,
  103. unsigned int width, unsigned int height,
  104. ColorMode mode, unsigned int bpp) {
  105. int id;
  106. assert(image != NULL);
  107. assert(width > 0);
  108. assert(height > 0);
  109. assert((bpp == 8) || (bpp == 24) || (bpp == 32));
  110. id = loadBufferSlot(image, width, height, mode, bpp, mTextureCount++);
  111. if (id < 0)
  112. return id;
  113. return id;
  114. }
  115. int TextureManager::loadBufferSlot(unsigned char *image,
  116. unsigned int width, unsigned int height,
  117. ColorMode mode, unsigned int bpp,
  118. unsigned int slot) {
  119. unsigned char bytes;
  120. unsigned int glcMode;
  121. assert(mTextureIds != NULL);
  122. assert(slot < mTextureLimit);
  123. assert(image != NULL);
  124. assert(width > 0);
  125. assert(height > 0);
  126. assert((bpp == 8) || (bpp == 24) || (bpp == 32));
  127. switch (mode) {
  128. case GREYSCALE:
  129. if (bpp != 8) {
  130. printf("TextureManager::Load ERROR Unsupported GREYSCALE, %i bpp\n", bpp);
  131. return -1;
  132. }
  133. bytes = 1;
  134. glcMode = GL_LUMINANCE;
  135. break;
  136. case RGB:
  137. if (bpp != 24) {
  138. printf("TextureManager::Load ERROR Unsupported RGB, %i bpp\n", bpp);
  139. return -1;
  140. }
  141. bytes = 3;
  142. glcMode = GL_RGB;
  143. break;
  144. case ARGB:
  145. if (bpp == 32) {
  146. argb2rgba32(image, width, height);
  147. } else {
  148. printf("TextureManager::Load ERROR Unsupported ARGB, %i bpp\n", bpp);
  149. return -1;
  150. }
  151. bytes = 4;
  152. glcMode = GL_RGBA;
  153. break;
  154. case RGBA:
  155. if (bpp != 32) {
  156. printf("TextureManager::Load ERROR Unsupported RGBA, %i bpp\n", bpp);
  157. return -1;
  158. }
  159. bytes = 4;
  160. glcMode = GL_RGBA;
  161. break;
  162. case BGR:
  163. if (bpp != 24) {
  164. printf("TextureManager::Load ERROR Unsupported BGR, %i bpp\n", bpp);
  165. return -1;
  166. }
  167. bytes = 3;
  168. glcMode = GL_BGR_EXT;
  169. break;
  170. case BGRA:
  171. if (bpp != 32) {
  172. printf("TextureManager::Load ERROR Unsupported BGRA, %i bpp\n", bpp);
  173. return -1;
  174. }
  175. bytes = 4;
  176. glcMode = GL_BGRA_EXT;
  177. break;
  178. }
  179. glClearColor(0.0, 0.0, 0.0, 0.0);
  180. glEnable(GL_DEPTH_TEST);
  181. glShadeModel(GL_SMOOTH);
  182. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  183. glBindTexture(GL_TEXTURE_2D, mTextureIds[slot]);
  184. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  185. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  186. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  187. if (mFlags & fUseMipmaps) {
  188. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  189. GL_NEAREST_MIPMAP_LINEAR);
  190. //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  191. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  192. GL_LINEAR_MIPMAP_LINEAR);
  193. glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
  194. glTexImage2D(GL_TEXTURE_2D, 0, bytes, width, height, 0, glcMode, GL_UNSIGNED_BYTE, image);
  195. } else {
  196. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  197. glTexImage2D(GL_TEXTURE_2D, 0, glcMode, width, height, 0,
  198. glcMode, GL_UNSIGNED_BYTE, image);
  199. }
  200. //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  201. return slot;
  202. }
  203. void TextureManager::bindTextureId(unsigned int n) {
  204. assert(mTextureIds != NULL);
  205. assert(n <= mTextureCount);
  206. glEnable(GL_TEXTURE_2D);
  207. //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  208. glBindTexture(GL_TEXTURE_2D, mTextureIds[n]);
  209. }
  210. int TextureManager::loadPCX(const char *filename) {
  211. assert(filename != NULL);
  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 = loadBuffer(image, w, h, c, bpp);
  225. delete [] image;
  226. }
  227. return id;
  228. }
  229. int TextureManager::loadTGA(const char *filename) {
  230. assert(filename != NULL);
  231. assert(filename[0] != '\0');
  232. unsigned char *image = NULL;
  233. unsigned char *image2 = NULL;
  234. unsigned int w, h;
  235. char type;
  236. int id = -1;
  237. if (!tgaCheck(filename)) {
  238. tgaLoad(filename, &image, &w, &h, &type);
  239. image2 = scaleBuffer(image, &w, &h, (type == 2) ? 32 : 24);
  240. if (image2) {
  241. delete [] image;
  242. image = image2;
  243. }
  244. if (image) {
  245. id = loadBuffer(image, w, h,
  246. (type == 2) ? RGBA : RGB,
  247. (type == 2) ? 32 : 24);
  248. delete [] image;
  249. }
  250. }
  251. if (id == -1) {
  252. printf("TextureManager::loadTGA> ERROR: Failed to load '%s'\n", filename);
  253. }
  254. return id;
  255. }