OGLTexture.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. // Copyright (c) 2008-2022 the Urho3D project
  2. // License: MIT
  3. #include "../../Precompiled.h"
  4. #include "../../Graphics/Graphics.h"
  5. #include "../../Graphics/Material.h"
  6. #include "../../GraphicsAPI/GraphicsImpl.h"
  7. #include "../../GraphicsAPI/RenderSurface.h"
  8. #include "../../IO/Log.h"
  9. #include "../../Resource/ResourceCache.h"
  10. #include "../../Resource/XMLFile.h"
  11. #include "../../DebugNew.h"
  12. namespace Urho3D
  13. {
  14. static GLenum glWrapModes[] =
  15. {
  16. GL_REPEAT,
  17. GL_MIRRORED_REPEAT,
  18. GL_CLAMP_TO_EDGE,
  19. #ifndef GL_ES_VERSION_2_0
  20. GL_CLAMP
  21. #else
  22. GL_CLAMP_TO_EDGE
  23. #endif
  24. };
  25. #ifndef GL_ES_VERSION_2_0
  26. static GLenum gl3WrapModes[] =
  27. {
  28. GL_REPEAT,
  29. GL_MIRRORED_REPEAT,
  30. GL_CLAMP_TO_EDGE,
  31. GL_CLAMP_TO_BORDER
  32. };
  33. #endif
  34. static GLenum GetWrapMode(TextureAddressMode mode)
  35. {
  36. #ifndef GL_ES_VERSION_2_0
  37. return Graphics::GetGL3Support() ? gl3WrapModes[mode] : glWrapModes[mode];
  38. #else
  39. return glWrapModes[mode];
  40. #endif
  41. }
  42. void Texture::SetSRGB_OGL(bool enable)
  43. {
  44. if (graphics_)
  45. enable &= graphics_->GetSRGBSupport();
  46. if (enable != sRGB_)
  47. {
  48. sRGB_ = enable;
  49. // If texture had already been created, must recreate it to set the sRGB texture format
  50. if (object_.name_)
  51. Create();
  52. // If texture in use in the framebuffer, mark it dirty
  53. if (graphics_ && graphics_->GetRenderTarget(0) && graphics_->GetRenderTarget(0)->GetParentTexture() == this)
  54. graphics_->MarkFBODirty_OGL();
  55. }
  56. }
  57. void Texture::UpdateParameters_OGL()
  58. {
  59. if (!object_.name_ || !graphics_)
  60. return;
  61. // If texture is multisampled, do not attempt to set parameters as it's illegal, just return
  62. #ifndef GL_ES_VERSION_2_0
  63. if (target_ == GL_TEXTURE_2D_MULTISAMPLE)
  64. {
  65. parametersDirty_ = false;
  66. return;
  67. }
  68. #endif
  69. // Wrapping
  70. glTexParameteri(target_, GL_TEXTURE_WRAP_S, GetWrapMode(addressModes_[COORD_U]));
  71. glTexParameteri(target_, GL_TEXTURE_WRAP_T, GetWrapMode(addressModes_[COORD_V]));
  72. #ifndef GL_ES_VERSION_2_0
  73. glTexParameteri(target_, GL_TEXTURE_WRAP_R, GetWrapMode(addressModes_[COORD_W]));
  74. #endif
  75. TextureFilterMode filterMode = filterMode_;
  76. if (filterMode == FILTER_DEFAULT)
  77. filterMode = graphics_->GetDefaultTextureFilterMode();
  78. // Filtering
  79. switch (filterMode)
  80. {
  81. case FILTER_NEAREST:
  82. if (levels_ < 2)
  83. glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  84. else
  85. glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  86. glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  87. break;
  88. case FILTER_BILINEAR:
  89. if (levels_ < 2)
  90. glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  91. else
  92. glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  93. glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  94. break;
  95. case FILTER_ANISOTROPIC:
  96. case FILTER_TRILINEAR:
  97. if (levels_ < 2)
  98. glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  99. else
  100. glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  101. glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  102. break;
  103. case FILTER_NEAREST_ANISOTROPIC:
  104. if (levels_ < 2)
  105. glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  106. else
  107. glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
  108. glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  109. break;
  110. default:
  111. break;
  112. }
  113. #ifndef GL_ES_VERSION_2_0
  114. // Anisotropy
  115. if (graphics_->GetAnisotropySupport())
  116. {
  117. unsigned maxAnisotropy = anisotropy_ ? anisotropy_ : graphics_->GetDefaultTextureAnisotropy();
  118. glTexParameterf(target_, GL_TEXTURE_MAX_ANISOTROPY_EXT,
  119. (filterMode == FILTER_ANISOTROPIC || filterMode == FILTER_NEAREST_ANISOTROPIC) ? (float)maxAnisotropy : 1.0f);
  120. }
  121. // Shadow compare
  122. if (shadowCompare_)
  123. {
  124. glTexParameteri(target_, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
  125. glTexParameteri(target_, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
  126. }
  127. else
  128. glTexParameteri(target_, GL_TEXTURE_COMPARE_MODE, GL_NONE);
  129. glTexParameterfv(target_, GL_TEXTURE_BORDER_COLOR, borderColor_.Data());
  130. #endif
  131. parametersDirty_ = false;
  132. }
  133. bool Texture::GetParametersDirty_OGL() const
  134. {
  135. return parametersDirty_;
  136. }
  137. bool Texture::IsCompressed_OGL() const
  138. {
  139. return format_ == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format_ == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
  140. format_ == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT || format_ == GL_ETC1_RGB8_OES ||
  141. format_ == GL_ETC2_RGB8_OES || format_ == GL_ETC2_RGBA8_OES ||
  142. format_ == COMPRESSED_RGB_PVRTC_4BPPV1_IMG || format_ == COMPRESSED_RGBA_PVRTC_4BPPV1_IMG ||
  143. format_ == COMPRESSED_RGB_PVRTC_2BPPV1_IMG || format_ == COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  144. }
  145. unsigned Texture::GetRowDataSize_OGL(int width) const
  146. {
  147. switch (format_)
  148. {
  149. case GL_ALPHA:
  150. case GL_LUMINANCE:
  151. return (unsigned)width;
  152. case GL_LUMINANCE_ALPHA:
  153. return (unsigned)(width * 2);
  154. case GL_RGB:
  155. return (unsigned)(width * 3);
  156. case GL_RGBA:
  157. #ifndef GL_ES_VERSION_2_0
  158. case GL_DEPTH24_STENCIL8_EXT:
  159. case GL_RG16:
  160. case GL_RG16F:
  161. case GL_R32F:
  162. #endif
  163. return (unsigned)(width * 4);
  164. #ifndef GL_ES_VERSION_2_0
  165. case GL_R8:
  166. return (unsigned)width;
  167. case GL_RG8:
  168. case GL_R16F:
  169. return (unsigned)(width * 2);
  170. case GL_RGBA16:
  171. case GL_RGBA16F_ARB:
  172. return (unsigned)(width * 8);
  173. case GL_RGBA32F_ARB:
  174. return (unsigned)(width * 16);
  175. #endif
  176. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  177. return ((unsigned)(width + 3) >> 2u) * 8;
  178. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  179. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  180. return ((unsigned)(width + 3) >> 2u) * 16;
  181. case GL_ETC1_RGB8_OES:
  182. case GL_ETC2_RGB8_OES:
  183. return ((unsigned)(width + 3) >> 2u) * 8;
  184. case GL_ETC2_RGBA8_OES:
  185. return ((unsigned)(width + 3) >> 2u) * 16;
  186. case COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  187. case COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  188. return ((unsigned)(width + 3) >> 2u) * 8;
  189. case COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  190. case COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  191. return ((unsigned)(width + 7) >> 3u) * 8;
  192. default:
  193. return 0;
  194. }
  195. }
  196. unsigned Texture::GetExternalFormat_OGL(unsigned format)
  197. {
  198. #ifndef GL_ES_VERSION_2_0
  199. if (format == GL_DEPTH_COMPONENT16 || format == GL_DEPTH_COMPONENT24 || format == GL_DEPTH_COMPONENT32)
  200. return GL_DEPTH_COMPONENT;
  201. else if (format == GL_DEPTH24_STENCIL8_EXT)
  202. return GL_DEPTH_STENCIL_EXT;
  203. else if (format == GL_SLUMINANCE_EXT)
  204. return GL_LUMINANCE;
  205. else if (format == GL_SLUMINANCE_ALPHA_EXT)
  206. return GL_LUMINANCE_ALPHA;
  207. else if (format == GL_R8 || format == GL_R16F || format == GL_R32F)
  208. return GL_RED;
  209. else if (format == GL_RG8 || format == GL_RG16 || format == GL_RG16F || format == GL_RG32F)
  210. return GL_RG;
  211. else if (format == GL_RGBA16 || format == GL_RGBA16F_ARB || format == GL_RGBA32F_ARB || format == GL_SRGB_ALPHA_EXT)
  212. return GL_RGBA;
  213. else if (format == GL_SRGB_EXT)
  214. return GL_RGB;
  215. else
  216. return format;
  217. #else
  218. return format;
  219. #endif
  220. }
  221. unsigned Texture::GetDataType_OGL(unsigned format)
  222. {
  223. #ifndef GL_ES_VERSION_2_0
  224. if (format == GL_DEPTH24_STENCIL8_EXT)
  225. return GL_UNSIGNED_INT_24_8_EXT;
  226. else if (format == GL_RG16 || format == GL_RGBA16)
  227. return GL_UNSIGNED_SHORT;
  228. else if (format == GL_RGBA32F_ARB || format == GL_RG32F || format == GL_R32F)
  229. return GL_FLOAT;
  230. else if (format == GL_RGBA16F_ARB || format == GL_RG16F || format == GL_R16F)
  231. return GL_HALF_FLOAT_ARB;
  232. else
  233. return GL_UNSIGNED_BYTE;
  234. #else
  235. if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_COMPONENT24_OES)
  236. return GL_UNSIGNED_INT;
  237. else if (format == GL_DEPTH_COMPONENT16)
  238. return GL_UNSIGNED_SHORT;
  239. else
  240. return GL_UNSIGNED_BYTE;
  241. #endif
  242. }
  243. unsigned Texture::GetSRGBFormat_OGL(unsigned format)
  244. {
  245. #ifndef GL_ES_VERSION_2_0
  246. if (!graphics_ || !graphics_->GetSRGBSupport())
  247. return format;
  248. switch (format)
  249. {
  250. case GL_RGB:
  251. return GL_SRGB_EXT;
  252. case GL_RGBA:
  253. return GL_SRGB_ALPHA_EXT;
  254. case GL_LUMINANCE:
  255. return GL_SLUMINANCE_EXT;
  256. case GL_LUMINANCE_ALPHA:
  257. return GL_SLUMINANCE_ALPHA_EXT;
  258. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  259. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  260. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  261. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  262. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  263. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  264. default:
  265. return format;
  266. }
  267. #else
  268. return format;
  269. #endif
  270. }
  271. void Texture::RegenerateLevels_OGL()
  272. {
  273. if (!object_.name_)
  274. return;
  275. #ifndef GL_ES_VERSION_2_0
  276. if (Graphics::GetGL3Support())
  277. glGenerateMipmap(target_);
  278. else
  279. glGenerateMipmapEXT(target_);
  280. #else
  281. glGenerateMipmap(target_);
  282. #endif
  283. levelsDirty_ = false;
  284. }
  285. }