gfxGLTextureArray.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include "gfxGLTextureArray.h"
  2. #include "gfxGLTextureObject.h"
  3. #include "gfxGLUtils.h"
  4. #include "core/util/tVector.h"
  5. #include "gfx/bitmap/imageUtils.h"
  6. GFXGLTextureArray::GFXGLTextureArray()
  7. {
  8. mTextureArray = NULL;
  9. }
  10. GFXGLTextureArray::~GFXGLTextureArray()
  11. {
  12. glDeleteTextures(1, &mTextureArray);
  13. }
  14. bool GFXGLTextureArray::fromTextureArray(const Vector<GFXTexHandle> &textureArray)
  15. {
  16. bool success = true;
  17. if (textureArray.empty())
  18. {
  19. return true;
  20. }
  21. bool found = false;
  22. U32 baseWidth = 0, baseHeight = 0;
  23. bool isCompressed = false;
  24. mArraySize = textureArray.size();
  25. for (GFXTexHandle texObj : textureArray)
  26. {
  27. if (texObj.isValid())
  28. {
  29. if (!found)
  30. {
  31. baseWidth = texObj.getWidth();
  32. baseHeight = texObj.getHeight();
  33. mMipMapLevels = getMax((U32)1, texObj->mMipLevels);
  34. found = true;
  35. mFormat = texObj.getFormat();
  36. isCompressed = ImageUtil::isCompressedFormat(mFormat);
  37. }
  38. if (mFormat != texObj.getFormat() || baseWidth != texObj.getWidth() || baseHeight != texObj.getHeight())
  39. {
  40. AssertWarn(true, "GFXGLTextureArray::fromTextureArray there was a mismatch in texture format, defaulting to uncompressed format");
  41. Con::warnf("GFXGLTextureArray::fromTextureArray there was a mismatch in texture format, defaulting to uncompressed format");
  42. success = false;
  43. mFormat = GFXFormatR8G8B8A8;
  44. isCompressed = false;
  45. }
  46. }
  47. }
  48. // One might think this should return false in this case, but the return value is mostly to highlight internal errors not input errors.
  49. if (!found) return true;
  50. Vector <GFXGLTextureObject*> texture2Ds;
  51. texture2Ds.setSize(textureArray.size());
  52. Vector<GFXTexHandle> tmpHandles;
  53. for (U32 idx = 0; idx < mArraySize; ++idx)
  54. {
  55. texture2Ds[idx] = NULL;
  56. GFXTexHandle texObj = textureArray[idx];
  57. if (texObj.isValid())
  58. {
  59. GFXTexHandle handle = textureArray[idx];
  60. if (texObj->getPath().isNotEmpty())
  61. {
  62. if (texObj.getHeight() != baseHeight|| texObj.getWidth() != baseWidth || texObj.getFormat() != mFormat)
  63. {
  64. if (texObj.getHeight() != baseHeight || texObj.getWidth() != baseWidth)
  65. {
  66. AssertWarn(true, "GFXGLTextureArray::fromTextureArray all textures should be the same size");
  67. Con::warnf("GFXGLTextureArray::fromTextureArray all textures should be the same size");
  68. }
  69. else
  70. {
  71. AssertWarn(true, "GFXGLTextureArray::fromTextureArray all textures should have the same format");
  72. Con::warnf("GFXGLTextureArray::fromTextureArray all textures should have the same format");
  73. }
  74. GBitmap* inBitmap = TEXMGR->loadUncompressedTexture(textureArray[idx]->getPath(), &GFXTexturePersistentProfile, baseWidth, baseHeight);
  75. if (!inBitmap->setFormat(mFormat))
  76. {
  77. AssertWarn(true, "GFXGLTextureArray::fromTextureArray all textures must be convertible to GFXFormatR8G8B8A8");
  78. Con::errorf("GFXGLTextureArray::fromTextureArray all textures must be convertible to GFXFormatR8G8B8A8");
  79. success = false;
  80. handle = NULL;
  81. delete inBitmap;
  82. }
  83. else
  84. {
  85. handle = TEXMGR->createTexture(inBitmap, "", &GFXStaticTextureProfile, true);
  86. tmpHandles.push_back(handle);
  87. }
  88. }
  89. }
  90. if (handle.isValid())
  91. {
  92. if (handle.getHeight() != baseHeight || handle.getWidth()!= baseWidth || handle.getFormat() != mFormat)
  93. {
  94. AssertWarn(true, "GFXGLTextureArray::fromTextureArray all textures must have the same size and format");
  95. Con::errorf("GFXGLTextureArray::fromTextureArray all textures must have the same size and format");
  96. success = false;
  97. }
  98. texture2Ds[idx] = dynamic_cast<GFXGLTextureObject*>(handle.getPointer());
  99. tmpHandles.push_back(handle);
  100. }
  101. }
  102. }
  103. glGenTextures(1, &mTextureArray);
  104. PRESERVE_2D_TEXTURE_ARRAY();
  105. glBindTexture(GL_TEXTURE_2D_ARRAY, mTextureArray);
  106. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mMin(mMipMapLevels - 1, 1));
  107. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  108. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  109. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  110. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  111. glTexStorage3D(GL_TEXTURE_2D_ARRAY, mMipMapLevels, GL_RGBA8, baseWidth, baseHeight, textureArray.size());
  112. for (U32 idx = 0; idx < texture2Ds.size(); ++idx)
  113. {
  114. if (texture2Ds[idx] == NULL)
  115. {
  116. continue;
  117. }
  118. GFXGLTextureObject* texObj = texture2Ds[idx];
  119. for (U32 mip = 0; mip < mMipMapLevels; ++mip)
  120. {
  121. U8* buf = texObj->getTextureData(mip);
  122. const U32 mipWidth = getMax(U32(1), baseWidth >> mip);
  123. const U32 mipHeight = getMax(U32(1), baseHeight >> mip);
  124. glBindTexture(GL_TEXTURE_2D_ARRAY, mTextureArray);
  125. if (isCompressed)
  126. {
  127. glCompressedTexSubImage3D(
  128. GL_TEXTURE_2D_ARRAY,
  129. mip, 0, 0,
  130. idx, mipWidth, mipHeight, 1,
  131. GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], buf
  132. );
  133. }
  134. else
  135. {
  136. glTexSubImage3D(
  137. GL_TEXTURE_2D_ARRAY,
  138. mip, 0, 0,
  139. idx, mipWidth, mipHeight, 1,
  140. GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], buf
  141. );
  142. }
  143. glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
  144. delete[] buf;
  145. }
  146. }
  147. if (!isCompressed)
  148. glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
  149. // Clean temporary textures
  150. for (GFXTexHandle handle : tmpHandles)
  151. {
  152. handle.free();
  153. }
  154. return success;
  155. }
  156. void GFXGLTextureArray::setToTexUnit(U32 tuNum)
  157. {
  158. dynamic_cast<GFXGLDevice*>(getOwningDevice())->setTextureArrayInternal(tuNum, this);
  159. }
  160. void GFXGLTextureArray::Release()
  161. {
  162. glDeleteTextures(1, &mTextureArray);
  163. mTextureArray = 0;
  164. }
  165. void GFXGLTextureArray::bind(U32 textureUnit) const
  166. {
  167. glActiveTexture(GL_TEXTURE0 + textureUnit);
  168. glBindTexture(GL_TEXTURE_2D_ARRAY, mTextureArray);
  169. dynamic_cast<GFXGLDevice*>(getOwningDevice())->getOpenglCache()->setCacheBindedTex(textureUnit, GL_TEXTURE_2D_ARRAY, mTextureArray);
  170. GFXGLStateBlockRef sb = static_cast<GFXGLDevice*>(GFX)->getCurrentStateBlock();
  171. AssertFatal(sb, "GFXGLTextureArray::bind - No active stateblock!");
  172. if (!sb)
  173. return;
  174. const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit];
  175. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0));
  176. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]);
  177. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mMin(mMipMapLevels - 1, 1));
  178. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]);
  179. glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]);
  180. }
  181. void GFXGLTextureArray::zombify()
  182. {
  183. }
  184. void GFXGLTextureArray::resurrect()
  185. {
  186. }