Texture.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #include <GL/glew.h>
  2. #include "Texture.h"
  3. #include "Renderer.h"
  4. #include "Image.h"
  5. #define LAST_TEX_UNIT (textureUnitsNum - 1)
  6. //======================================================================================================================
  7. // Statics =
  8. //======================================================================================================================
  9. int Texture::textureUnitsNum = -1;
  10. bool Texture::mipmappingEnabled = true;
  11. bool Texture::compressionEnabled = false;
  12. int Texture::anisotropyLevel = 8;
  13. //======================================================================================================================
  14. // Constructor =
  15. //======================================================================================================================
  16. Texture::Texture():
  17. Resource(RT_TEXTURE),
  18. glId(numeric_limits<uint>::max()),
  19. target(GL_TEXTURE_2D)
  20. {}
  21. //======================================================================================================================
  22. // load =
  23. //======================================================================================================================
  24. bool Texture::load(const char* filename)
  25. {
  26. target = GL_TEXTURE_2D;
  27. if(isLoaded())
  28. {
  29. ERROR("Texture already loaded");
  30. return false;
  31. }
  32. Image img;
  33. if(!img.load(filename))
  34. return false;
  35. // bind the texture
  36. glGenTextures(1, &glId);
  37. bind(LAST_TEX_UNIT);
  38. if(mipmappingEnabled)
  39. setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  40. else
  41. setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  42. setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  43. setTexParameter(GL_TEXTURE_MAX_ANISOTROPY_EXT, float(anisotropyLevel));
  44. // leave to GL_REPEAT. There is not real performance hit
  45. setRepeat(true);
  46. // chose formats
  47. int internalFormat;
  48. int format;
  49. int type;
  50. switch(img.getType())
  51. {
  52. case Image::CT_R:
  53. internalFormat = (compressionEnabled) ? GL_COMPRESSED_RED : GL_RED;
  54. format = GL_RED;
  55. type = GL_UNSIGNED_BYTE;
  56. break;
  57. case Image::CT_RGB:
  58. internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGB : GL_RGB;
  59. format = GL_RGB;
  60. type = GL_UNSIGNED_BYTE;
  61. break;
  62. case Image::CT_RGBA:
  63. internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGBA : GL_RGBA;
  64. format = GL_RGBA;
  65. type = GL_UNSIGNED_BYTE;
  66. break;
  67. default:
  68. FATAL("See file");
  69. }
  70. glTexImage2D(target, 0, internalFormat, img.getWidth(), img.getHeight(), 0, format, type, &img.getData()[0]);
  71. if(mipmappingEnabled)
  72. glGenerateMipmap(target);
  73. setMipmapLevel(3);
  74. return GL_OK();
  75. }
  76. //======================================================================================================================
  77. // createEmpty2D =
  78. //======================================================================================================================
  79. bool Texture::createEmpty2D(float width_, float height_, int internalFormat, int format_, uint type_)
  80. {
  81. target = GL_TEXTURE_2D;
  82. DEBUG_ERR(internalFormat > 0 && internalFormat <= 4); // deprecated internal format
  83. DEBUG_ERR(isLoaded());
  84. // GL stuff
  85. glGenTextures(1, &glId);
  86. bind(LAST_TEX_UNIT);
  87. setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  88. setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  89. setRepeat(true);
  90. // allocate to vram
  91. glTexImage2D(target, 0, internalFormat, width_, height_, 0, format_, type_, NULL);
  92. return GL_OK();
  93. }
  94. //======================================================================================================================
  95. // createEmpty2DMSAA =
  96. //======================================================================================================================
  97. bool Texture::createEmpty2DMsaa(int samplesNum, int internalFormat, int width_, int height_, bool mimapping)
  98. {
  99. target = GL_TEXTURE_2D_MULTISAMPLE;
  100. DEBUG_ERR(isLoaded());
  101. glGenTextures(1, &glId);
  102. bind(LAST_TEX_UNIT);
  103. // allocate
  104. glTexImage2DMultisample(target, samplesNum, internalFormat, width_, height_, false);
  105. if(mimapping)
  106. glGenerateMipmap(target);
  107. return GL_OK();
  108. }
  109. //======================================================================================================================
  110. // unload =
  111. //======================================================================================================================
  112. void Texture::unload()
  113. {
  114. if(isLoaded())
  115. glDeleteTextures(1, &glId);
  116. }
  117. //======================================================================================================================
  118. // bind =
  119. //======================================================================================================================
  120. void Texture::bind(uint unit) const
  121. {
  122. if(unit >= static_cast<uint>(textureUnitsNum))
  123. WARNING("Max tex units passed");
  124. glActiveTexture(GL_TEXTURE0 + unit);
  125. glBindTexture(target, getGlId());
  126. }
  127. //======================================================================================================================
  128. // getWidth =
  129. //======================================================================================================================
  130. int Texture::getWidth() const
  131. {
  132. bind(LAST_TEX_UNIT);
  133. int i;
  134. glGetTexLevelParameteriv(target, 0, GL_TEXTURE_WIDTH, &i);
  135. return i;
  136. }
  137. //======================================================================================================================
  138. // getHeight =
  139. //======================================================================================================================
  140. int Texture::getHeight() const
  141. {
  142. bind(LAST_TEX_UNIT);
  143. int i;
  144. glGetTexLevelParameteriv(target, 0, GL_TEXTURE_HEIGHT, &i);
  145. return i;
  146. }
  147. //======================================================================================================================
  148. // setTexParameter [int] =
  149. //======================================================================================================================
  150. void Texture::setTexParameter(uint paramName, int value) const
  151. {
  152. bind(LAST_TEX_UNIT);
  153. glTexParameteri(target, paramName, value);
  154. }
  155. //======================================================================================================================
  156. // setTexParameter [float] =
  157. //======================================================================================================================
  158. void Texture::setTexParameter(uint paramName, float value) const
  159. {
  160. bind(LAST_TEX_UNIT);
  161. glTexParameterf(target, paramName, value);
  162. }
  163. //======================================================================================================================
  164. // setRepeat =
  165. //======================================================================================================================
  166. void Texture::setRepeat(bool repeat) const
  167. {
  168. bind(LAST_TEX_UNIT);
  169. if(repeat)
  170. {
  171. setTexParameter(GL_TEXTURE_WRAP_S, GL_REPEAT);
  172. setTexParameter(GL_TEXTURE_WRAP_T, GL_REPEAT);
  173. }
  174. else
  175. {
  176. setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP);
  177. setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP);
  178. }
  179. }
  180. //======================================================================================================================
  181. // getBaseLevel =
  182. //======================================================================================================================
  183. int Texture::getBaseLevel() const
  184. {
  185. bind(LAST_TEX_UNIT);
  186. int level;
  187. glGetTexParameteriv(target, GL_TEXTURE_BASE_LEVEL, &level);
  188. return level;
  189. }
  190. //======================================================================================================================
  191. // getActiveTexUnit =
  192. //======================================================================================================================
  193. uint Texture::getActiveTexUnit()
  194. {
  195. int unit;
  196. glGetIntegerv(GL_ACTIVE_TEXTURE, &unit);
  197. return unit - GL_TEXTURE0;
  198. }
  199. //======================================================================================================================
  200. // getBindedTexId =
  201. //======================================================================================================================
  202. uint Texture::getBindedTexId(uint unit)
  203. {
  204. int id;
  205. glActiveTexture(GL_TEXTURE0 + unit);
  206. glGetIntegerv(GL_TEXTURE_BINDING_2D, &id);
  207. return id;
  208. }
  209. //======================================================================================================================
  210. // getMaxLevel =
  211. //======================================================================================================================
  212. int Texture::getMaxLevel() const
  213. {
  214. bind(LAST_TEX_UNIT);
  215. int level;
  216. glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &level);
  217. return level;
  218. }
  219. //======================================================================================================================
  220. // setAnisotropy =
  221. //======================================================================================================================
  222. void Texture::setAnisotropy(uint level)
  223. {
  224. bind(LAST_TEX_UNIT);
  225. setTexParameter(GL_TEXTURE_MAX_ANISOTROPY_EXT, int(level));
  226. }
  227. //======================================================================================================================
  228. // setMipmapLevel =
  229. //======================================================================================================================
  230. void Texture::setMipmapLevel(uint level)
  231. {
  232. bind(LAST_TEX_UNIT);
  233. setTexParameter(GL_TEXTURE_BASE_LEVEL, int(level));
  234. }