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.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. }