Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TextureManager.cpp 8.3KB

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