Browse Source

Refactor GFXTextureArray

Lukas Aldershaab 4 years ago
parent
commit
e92e945912

+ 31 - 147
Engine/source/gfx/D3D11/gfxD3D11TextureArray.cpp

@@ -5,164 +5,47 @@
 #include "gfxD3D11Device.h"
 #include "gfxD3D11EnumTranslate.h"
 #include "core/util/tVector.h"
-#include "gfx/gfxDebugEvent.h"
-#include "gfx/bitmap/imageUtils.h"
 #include "gfx/util/screenspace.h"
 #include "shaderGen/shaderFeature.h"
 
 
-bool GFXD3D11TextureArray::fromTextureArray(const Vector<GFXTexHandle> &textureArray)
+void GFXD3D11TextureArray::init()
 {
-   bool success = true;
-   Vector<ID3D11Texture2D*> texture2Ds;
-   texture2Ds.setSize(textureArray.size());
-   Vector<GFXTexHandle> tmpHandles;
+   mTextureArrayDesc.Width = mWidth;
+   mTextureArrayDesc.Height = mHeight;
+   mTextureArrayDesc.MipLevels = mMipLevels;
+   mTextureArrayDesc.ArraySize = mArraySize;
+   mTextureArrayDesc.Format = GFXD3D11TextureFormat[mFormat];
+   mTextureArrayDesc.SampleDesc.Count = 1;
+   mTextureArrayDesc.SampleDesc.Quality = 0;
+   mTextureArrayDesc.Usage = D3D11_USAGE_DEFAULT;
+   mTextureArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+   mTextureArrayDesc.CPUAccessFlags = 0;
+   mTextureArrayDesc.MiscFlags = 0;
+
+   HRESULT hr = D3D11DEVICE->CreateTexture2D(&mTextureArrayDesc, NULL, &mTextureArray);
+   AssertFatal(SUCCEEDED(hr), "GFXD3D11TextureArray::init failed to create texture array!");
 
-   mArraySize = textureArray.size();
-
-   //---------------------------------------------------------------------------------------
-   //	Create the texture array.  Each element in the texture 
-   //		array has the same format/dimensions.
-   //---------------------------------------------------------------------------------------
-   D3D11_TEXTURE2D_DESC texElementDesc;
-   GFXFormat format;
-   bool found = false;
-   for (U32 idx = 0; idx < mArraySize; ++idx)
-   {
-      GFXTexHandle texObj = textureArray[idx];
-      if (texObj.isValid())
-      {
-         if (!found)
-         {
-            dynamic_cast<GFXD3D11TextureObject*>(texObj.getPointer())->get2DTex()->GetDesc(&texElementDesc);
-            found = true;
-            format = texObj.getFormat();
-         }
-
-         if (format != texObj.getFormat() || texElementDesc.Width != texObj.getWidth() || texElementDesc.Height != texObj.getHeight())
-         {
-            AssertWarn(true, "GFXGLTextureArray::fromTextureArray there was a mismatch in texture formats, defaulting to uncompressed format");
-            Con::warnf("GFXGLTextureArray::fromTextureArray there was a mismatch in texture formats, defaulting to uncompressed format");
-            success = false;
-            format = GFXFormatR8G8B8A8;
-         }
-      }
-   }
-
-   // One might think this should return false in this case, but the return value is mostly to highlight internal errors not input errors.
-   if (!found) return true;
-
-   for (U32 idx = 0; idx < mArraySize; ++idx)
-   {
-      texture2Ds[idx] = NULL;
-
-      if(textureArray[idx].isValid())
-      {
-         GFXTexHandle handle = textureArray[idx];
-         if (textureArray[idx]->getPath().isNotEmpty())
-         {
-            D3D11_TEXTURE2D_DESC desc;
-            ID3D11Texture2D* tex = dynamic_cast<GFXD3D11TextureObject*>(textureArray[idx].getPointer())->get2DTex();
-            tex->GetDesc(&desc);
-            if (desc.Height != texElementDesc.Height || desc.Width != texElementDesc.Width || textureArray[idx].getFormat() != format)
-            {
-               if (desc.Height != texElementDesc.Height || desc.Width != texElementDesc.Width)
-               {
-                  AssertWarn(true, "GFXD3D11TextureArray::fromTextureArray all textures should be the same size");
-                  Con::warnf("GFXD3D11TextureArray::fromTextureArray all textures should be the same size");
-               }
-               else
-               {
-                  AssertWarn(true, "GFXD3D11TextureArray::fromTextureArray all textures should have the same format");
-                  Con::warnf("GFXD3D11TextureArray::fromTextureArray all textures should have the same format");
-               }
-
-               GBitmap* inBitmap = TEXMGR->loadUncompressedTexture(textureArray[idx]->getPath(), &GFXTexturePersistentProfile, texElementDesc.Width, texElementDesc.Height);
-               if (!inBitmap->setFormat(format))
-               {
-                  AssertWarn(true, "GFXD3D11TextureArray::fromTextureArray all textures must be convertible to GFXFormatR8G8B8A8");
-                  Con::errorf("GFXD3D11TextureArray::fromTextureArray all textures must be convertible to GFXFormatR8G8B8A8");
-                  success = false;
-                  handle = NULL;
-                  delete inBitmap;
-               }
-               else
-               {
-                  handle = TEXMGR->createTexture(inBitmap, "", &GFXStaticTextureProfile, true);
-                  tmpHandles.push_back(handle);
-               }
-            }
-         }
-         if (handle.isValid())
-         {
-            D3D11_TEXTURE2D_DESC desc;
-            ID3D11Texture2D* tex = dynamic_cast<GFXD3D11TextureObject*>(handle.getPointer())->get2DTex();
-            tex->GetDesc(&desc);
-            if (desc.Height != texElementDesc.Height || desc.Width != texElementDesc.Width || handle.getFormat() != format)
-            {
-               AssertWarn(true, "GFXD3D11TextureArray::fromTextureArray all textures must have the same size and format");
-               Con::errorf("GFXD3D11TextureArray::fromTextureArray all textures must have the same size and format");
-               success = false;
-            }
-            texture2Ds[idx] = dynamic_cast<GFXD3D11TextureObject*>(handle.getPointer())->get2DTex();
-         }
-      }
-   }
-
-   D3D11_TEXTURE2D_DESC texArrayDesc;
-   texArrayDesc.Width = texElementDesc.Width;
-   texArrayDesc.Height = texElementDesc.Height;
-   texArrayDesc.MipLevels = texElementDesc.MipLevels;
-   texArrayDesc.ArraySize = mArraySize;
-   texArrayDesc.Format = GFXD3D11TextureFormat[format];
-   texArrayDesc.SampleDesc.Count = 1;
-   texArrayDesc.SampleDesc.Quality = 0;
-   texArrayDesc.Usage = D3D11_USAGE_DEFAULT;
-   texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
-   texArrayDesc.CPUAccessFlags = 0;
-   texArrayDesc.MiscFlags = 0;
-
-   HRESULT hr = D3D11DEVICE->CreateTexture2D(&texArrayDesc, NULL, &mTextureArray);
-   AssertFatal(SUCCEEDED(hr), "GFXD3D11TextureArray::_createTextureArray failed to create texture array!");
    //---------------------------------------------------------------------------------------
-
-
+   //					Create a resource view to the texture array.
    //---------------------------------------------------------------------------------------
-   //	Copy individual texture elements into texture array.
+   createResourceView(mTextureArrayDesc.Format, mTextureArrayDesc.MipLevels, mTextureArrayDesc.BindFlags);
    //---------------------------------------------------------------------------------------
-   // for each texture element...
-   for (UINT i = 0; i < mArraySize; ++i)
-   {
-      if (texture2Ds[i] == NULL)
-      {
-         continue;
-      }
-      D3D11_TEXTURE2D_DESC desc;
-      texture2Ds[i]->GetDesc(&desc);
-      // for each mipmap level...
-      for (UINT j = 0; j < desc.MipLevels; ++j)
-      {
-         const U32 srcSubResource = D3D11CalcSubresource(j, 0, desc.MipLevels);
-         const U32 dstSubResource = D3D11CalcSubresource(j, i, texArrayDesc.MipLevels);
-         D3D11DEVICECONTEXT->CopySubresourceRegion(mTextureArray, dstSubResource, 0, 0, 0, texture2Ds[i], srcSubResource, NULL);
-      }
-   }
+}
 
-   // Clean temporary textures
-   for (GFXTexHandle handle : tmpHandles)
+void GFXD3D11TextureArray::_setTexture(const GFXTexHandle& texture, U32 slot)
+{
+   GFXD3D11TextureObject *texObj = dynamic_cast<GFXD3D11TextureObject*>(texture.getPointer());
+   ID3D11Texture2D* tex2d = texObj->get2DTex();
+   D3D11_TEXTURE2D_DESC desc;
+   tex2d->GetDesc(&desc);
+   // for each mipmap level...
+   for (UINT j = 0; j < desc.MipLevels; ++j)
    {
-      handle.free();
+      const U32 srcSubResource = D3D11CalcSubresource(j, 0, desc.MipLevels);
+      const U32 dstSubResource = D3D11CalcSubresource(j, slot, mTextureArrayDesc.MipLevels);
+      D3D11DEVICECONTEXT->CopySubresourceRegion(mTextureArray, dstSubResource, 0, 0, 0, tex2d, srcSubResource, NULL);
    }
-   //---------------------------------------------------------------------------------------
-
-
-   //---------------------------------------------------------------------------------------
-   //					Create a resource view to the texture array.
-   //---------------------------------------------------------------------------------------
-   createResourceView(texArrayDesc.Format, texArrayDesc.MipLevels, texArrayDesc.BindFlags);
-   //---------------------------------------------------------------------------------------
-
-   return success;
 }
 
 void GFXD3D11TextureArray::setToTexUnit(U32 tuNum)
@@ -170,7 +53,6 @@ void GFXD3D11TextureArray::setToTexUnit(U32 tuNum)
    D3D11DEVICECONTEXT->PSSetShaderResources(tuNum, 1, &mSRView);
 }
 
-
 void GFXD3D11TextureArray::createResourceView(DXGI_FORMAT format, U32 numMipLevels, U32 usageFlags)
 {
    HRESULT hr;
@@ -226,6 +108,8 @@ void GFXD3D11TextureArray::Release()
    SAFE_RELEASE(mRTView)
    SAFE_RELEASE(mDSView)
    SAFE_RELEASE(mTextureArray)
+
+   GFXTextureArray::Release();
 }
 
 ID3D11ShaderResourceView* GFXD3D11TextureArray::getSRView()

+ 7 - 2
Engine/source/gfx/D3D11/gfxD3D11TextureArray.h

@@ -20,7 +20,9 @@ public:
    {
    }
 
-   bool fromTextureArray(const Vector<GFXTexHandle> &textureArray) override;
+   ~GFXD3D11TextureArray() { Release();  };
+
+   void init();
    void setToTexUnit(U32 tuNum) override;
 
    void createResourceView(DXGI_FORMAT format, U32 numMipLevels, U32 usageFlags);
@@ -39,12 +41,15 @@ public:
    ID3D11RenderTargetView** getRTViewPtr();
    ID3D11DepthStencilView** getDSViewPtr();
 
+protected:
+   void _setTexture(const GFXTexHandle& texture, U32 slot) override;
+
 private:
    ID3D11ShaderResourceView* mSRView; // for shader resource input
    ID3D11RenderTargetView* mRTView; // for render targets
    ID3D11DepthStencilView* mDSView; //render target view for depth stencil
-
    ID3D11Texture2D* mTextureArray;
+   D3D11_TEXTURE2D_DESC mTextureArrayDesc;
 };
 
 

+ 5 - 2
Engine/source/gfx/Null/gfxNullDevice.cpp

@@ -184,8 +184,11 @@ public:
    void zombify() override {}
    void resurrect() override {}
    void Release() override {}
-   bool fromTextureArray(const Vector<GFXTexHandle> &textureArray) override { return true; }
-   virtual void setToTexUnit(U32 tuNum) { }
+   void setToTexUnit(U32 tuNum) override { }
+   void init() override { }
+
+protected:
+   void _setTexture(const GFXTexHandle& texture, U32 slot) override { }
 };
 
 class GFXNullVertexBuffer : public GFXVertexBuffer 

+ 137 - 0
Engine/source/gfx/gfxTextureArray.cpp

@@ -1,5 +1,142 @@
 #include "gfxTextureArray.h"
 
+
+
+#include "gfxDevice.h"
+#include "gfxTextureManager.h"
+#include "console/console.h"
+
+void GFXTextureArray::set(U32 width, U32 height, U32 size, GFXFormat format, U32 mipLevels)
+{
+   mWidth = width;
+   mHeight = height;
+   mArraySize = size;
+   mFormat = format;
+   mMipLevels = mipLevels;
+
+   mTextures.setSize(size);
+
+   init();
+}
+
+bool GFXTextureArray::fromTextureArray(const Vector<GFXTexHandle>& textureArray)
+{
+   bool success = true;
+
+   //---------------------------------------------------------------------------------------
+   //	Create the texture array.  Each element in the texture 
+   //		array has the same format/dimensions.
+   //---------------------------------------------------------------------------------------
+   bool found = false;
+   for (const GFXTexHandle& texObj : textureArray)
+   {
+      if (texObj.isValid())
+      {
+         if (!found)
+         {
+            found = true;
+            mFormat = texObj.getFormat();
+            mWidth = texObj.getWidth();
+            mHeight = texObj.getHeight();
+            mMipLevels = texObj->getMipLevels();
+         }
+
+         if (mFormat != texObj.getFormat() || mWidth != texObj.getWidth() || mHeight != texObj.getHeight())
+         {
+            AssertWarn(true, "GFXTextureArray::fromTextureArray there was a mismatch in texture formats, defaulting to uncompressed format");
+            Con::warnf("GFXTextureArray::fromTextureArray there was a mismatch in texture formats, defaulting to uncompressed format");
+            success = false;
+            mFormat = GFXFormatR8G8B8A8;
+         }
+      }
+   }
+
+   // One might think this should return false in this case, but the return value is mostly to highlight internal errors not input errors.
+   if (!found) return true;
+
+   set(mWidth, mHeight, textureArray.size(), mFormat, mMipLevels);
+
+   //---------------------------------------------------------------------------------------
+
+
+   //---------------------------------------------------------------------------------------
+   //	Copy individual texture elements into texture array.
+   //---------------------------------------------------------------------------------------
+   // for each texture element...
+   for (U32 i = 0; i < mArraySize; ++i)
+   {
+      if (textureArray[i].isValid())
+      {
+         setTexture(textureArray[i], i);
+      }
+   }
+   //---------------------------------------------------------------------------------------
+
+   return success;
+}
+
+void GFXTextureArray::setTexture(const GFXTexHandle& texture, U32 slot)
+{
+   GFXTexHandle handle = texture;
+   if (texture->getPath().isNotEmpty())
+   {
+      if (texture.getHeight() != mHeight || texture.getWidth() != mWidth || texture.getFormat() != mFormat || texture->getMipLevels() < mMipLevels)
+      {
+         if (texture.getHeight() != mHeight || texture.getWidth() != mWidth)
+         {
+            AssertWarn(true, "GFXTextureArray::setTexture all textures should be the same size");
+            Con::warnf("GFXTextureArray::setTexture all textures should be the same size");
+         }
+         else if (texture->getMipLevels() < mMipLevels)
+         {
+            AssertWarn(true, "GFXTextureArray::setTexture all textures should have at least the same number of mips");
+            Con::warnf("GFXTextureArray::setTexture all textures should have at least the same number of mips");
+         }
+         else
+         {
+            AssertWarn(true, "GFXTextureArray::setTexture all textures should have the same format");
+            Con::warnf("GFXTextureArray::setTexture all textures should have the same format");
+         }
+
+         GBitmap* inBitmap = TEXMGR->loadUncompressedTexture(texture->getPath(), &GFXTexturePersistentProfile, mWidth, mHeight);
+         if (!inBitmap->setFormat(mFormat))
+         {
+            AssertWarn(true, "GFXTextureArray::setTexture all textures must be convertible to GFXFormat " + mFormat);
+            Con::errorf("GFXTextureArray::setTexture all textures must be convertible to GFXFormat" + mFormat);
+            handle = NULL;
+            delete inBitmap;
+         }
+         else
+         {
+            handle = TEXMGR->createTexture(inBitmap, "", &GFXStaticTextureProfile, true);
+         }
+      }
+   }
+   if (!handle.isValid())
+   {
+      return;
+   }
+
+   if (handle.getHeight() != mHeight || handle.getWidth() != mWidth || handle.getFormat() != mFormat || handle->getMipLevels() < mMipLevels)
+   {
+      AssertWarn(true, "GFXTextureArray::setTexture all textures must have the same size and format");
+      Con::errorf("GFXTextureArray::setTexture all textures must have the same size and format");
+      return;
+   }
+
+   mTextures[slot] = handle;
+
+   _setTexture(handle, slot);
+}
+
+void GFXTextureArray::Release()
+{
+   for (GFXTexHandle& mTexture : mTextures)
+   {
+      mTexture = NULL;
+   }
+}
+
 const String GFXTextureArray::describeSelf() const
 {
    // We've got nothing

+ 15 - 2
Engine/source/gfx/gfxTextureArray.h

@@ -35,6 +35,7 @@
 #ifndef _GFXTEXTUREHANDLE_H_
 #include "gfxTextureHandle.h"
 #endif
+#include "core/util/tVector.h"
 
 
 class GFXTextureProfile;
@@ -43,18 +44,30 @@ class GFXTextureObject;
 class GFXTextureArray : public StrongRefBase, public GFXResource
 {
 public:
-   virtual bool fromTextureArray(const Vector<GFXTexHandle> &textureArray) = 0;
+   virtual void init() = 0;
+   virtual void set(U32 width, U32 height, U32 size, GFXFormat format, U32 mipLevels);
+   virtual bool fromTextureArray(const Vector<GFXTexHandle> &textureArray);
+   virtual void setTexture(const GFXTexHandle &texture, U32 slot);
    virtual void setToTexUnit(U32 tuNum) = 0;
 
 
    // GFXResource interface
    virtual void zombify() = 0;
    virtual void resurrect() = 0;
-   virtual void Release() = 0;
+   virtual void Release();
 
    virtual const String describeSelf() const;
 
+   GFXFormat mFormat;
+   U32 mWidth;
+   U32 mHeight;
    U32 mArraySize;
+   U32 mMipLevels;
+
+   Vector<GFXTexHandle> mTextures;
+
+protected:
+   virtual void _setTexture(const GFXTexHandle& texture, U32 slot) = 0;
 };
 
 

+ 32 - 150
Engine/source/gfx/gl/gfxGLTextureArray.cpp

@@ -3,175 +3,57 @@
 #include "gfxGLTextureObject.h"
 #include "gfxGLUtils.h"
 #include "core/util/tVector.h"
-#include "gfx/bitmap/imageUtils.h"
-
 
 GFXGLTextureArray::GFXGLTextureArray()
 {
    mTextureArray = NULL;
 }
 
-GFXGLTextureArray::~GFXGLTextureArray()
-{
-   glDeleteTextures(1, &mTextureArray);
-}
-
-bool GFXGLTextureArray::fromTextureArray(const Vector<GFXTexHandle> &textureArray)
+void GFXGLTextureArray::init()
 {
-   bool success = true;
-
-   if (textureArray.empty())
-   {
-      return true;
-   }
-
-   bool found = false;
-   U32 baseWidth = 0, baseHeight = 0;
-   bool isCompressed = false;
-   mArraySize = textureArray.size();
-
-   for (GFXTexHandle texObj : textureArray)
-   {
-      if (texObj.isValid())
-      {
-         if (!found)
-         {
-            baseWidth = texObj.getWidth();
-            baseHeight = texObj.getHeight();
-            mMipMapLevels = getMax((U32)1, texObj->mMipLevels);
-            found = true;
-            mFormat = texObj.getFormat();
-            isCompressed = ImageUtil::isCompressedFormat(mFormat);
-         }
-
-         if (mFormat != texObj.getFormat() || baseWidth != texObj.getWidth() || baseHeight != texObj.getHeight())
-         {
-            AssertWarn(true, "GFXGLTextureArray::fromTextureArray there was a mismatch in texture format, defaulting to uncompressed format");
-            Con::warnf("GFXGLTextureArray::fromTextureArray there was a mismatch in texture format, defaulting to uncompressed format");
-            success = false;
-            mFormat = GFXFormatR8G8B8A8;
-            isCompressed = false;
-         }
-      }
-   }
-
-   // One might think this should return false in this case, but the return value is mostly to highlight internal errors not input errors.
-   if (!found) return true;
-
-   Vector <GFXGLTextureObject*> texture2Ds;
-   texture2Ds.setSize(textureArray.size());
-   Vector<GFXTexHandle> tmpHandles;
-
-   for (U32 idx = 0; idx < mArraySize; ++idx)
-   {
-      texture2Ds[idx] = NULL;
-      GFXTexHandle texObj = textureArray[idx];
-
-      if (texObj.isValid())
-      {
-         GFXTexHandle handle = textureArray[idx];
-         if (texObj->getPath().isNotEmpty())
-         {
-            if (texObj.getHeight() != baseHeight|| texObj.getWidth() != baseWidth || texObj.getFormat() != mFormat)
-            {
-               if (texObj.getHeight() != baseHeight || texObj.getWidth() != baseWidth)
-               {
-                  AssertWarn(true, "GFXGLTextureArray::fromTextureArray all textures should be the same size");
-                  Con::warnf("GFXGLTextureArray::fromTextureArray all textures should be the same size");
-               }
-               else
-               {
-                  AssertWarn(true, "GFXGLTextureArray::fromTextureArray all textures should have the same format");
-                  Con::warnf("GFXGLTextureArray::fromTextureArray all textures should have the same format");
-               }
-
-               GBitmap* inBitmap = TEXMGR->loadUncompressedTexture(textureArray[idx]->getPath(), &GFXTexturePersistentProfile, baseWidth, baseHeight);
-               if (!inBitmap->setFormat(mFormat))
-               {
-                  AssertWarn(true, "GFXGLTextureArray::fromTextureArray all textures must be convertible to GFXFormatR8G8B8A8");
-                  Con::errorf("GFXGLTextureArray::fromTextureArray all textures must be convertible to GFXFormatR8G8B8A8");
-                  success = false;
-                  handle = NULL;
-                  delete inBitmap;
-               }
-               else
-               {
-                  handle = TEXMGR->createTexture(inBitmap, "", &GFXStaticTextureProfile, true);
-                  tmpHandles.push_back(handle);
-               }
-            }
-         }
-         if (handle.isValid())
-         {
-            if (handle.getHeight() != baseHeight || handle.getWidth()!= baseWidth || handle.getFormat() != mFormat)
-            {
-               AssertWarn(true, "GFXGLTextureArray::fromTextureArray all textures must have the same size and format");
-               Con::errorf("GFXGLTextureArray::fromTextureArray all textures must have the same size and format");
-               success = false;
-            }
-            texture2Ds[idx] = dynamic_cast<GFXGLTextureObject*>(handle.getPointer());
-            tmpHandles.push_back(handle);
-         }
-      }
-   }
-
    glGenTextures(1, &mTextureArray);
    PRESERVE_2D_TEXTURE_ARRAY();
    glBindTexture(GL_TEXTURE_2D_ARRAY, mTextureArray);
-   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mMin(mMipMapLevels - 1, 1));
+   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mMin(mMipLevels - 1, 1));
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-   glTexStorage3D(GL_TEXTURE_2D_ARRAY, mMipMapLevels, GL_RGBA8, baseWidth, baseHeight, textureArray.size());
+   glTexStorage3D(GL_TEXTURE_2D_ARRAY, mMipLevels, GL_RGBA8, mWidth, mHeight, mArraySize);
+}
 
-   for (U32 idx = 0; idx < texture2Ds.size(); ++idx)
+void GFXGLTextureArray::_setTexture(const GFXTexHandle& texture, U32 slot)
+{
+   PRESERVE_2D_TEXTURE_ARRAY();
+   glBindTexture(GL_TEXTURE_2D_ARRAY, mTextureArray);
+
+   GFXGLTextureObject* texObj = dynamic_cast<GFXGLTextureObject*>(texture.getPointer());
+   for (U32 mip = 0; mip < mMipLevels; ++mip)
    {
-      if (texture2Ds[idx] == NULL)
+      U8* buf = texObj->getTextureData(mip);
+      const U32 mipWidth = getMax(U32(1), mWidth >> mip);
+      const U32 mipHeight = getMax(U32(1), mHeight >> mip);
+      if (mIsCompressed)
       {
-         continue;
+         glCompressedTexSubImage3D(
+            GL_TEXTURE_2D_ARRAY,
+            mip, 0, 0,
+            slot, mipWidth, mipHeight, 1,
+            GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], buf
+         );
       }
-      GFXGLTextureObject* texObj = texture2Ds[idx];
-      for (U32 mip = 0; mip < mMipMapLevels; ++mip)
+      else
       {
-         U8* buf = texObj->getTextureData(mip);
-         const U32 mipWidth = getMax(U32(1), baseWidth >> mip);
-         const U32 mipHeight = getMax(U32(1), baseHeight >> mip);
-         glBindTexture(GL_TEXTURE_2D_ARRAY, mTextureArray);
-         if (isCompressed)
-         {
-            glCompressedTexSubImage3D(
-               GL_TEXTURE_2D_ARRAY,
-               mip, 0, 0,
-               idx, mipWidth, mipHeight, 1,
-               GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], buf
-            );
-         }
-         else
-         {
-            glTexSubImage3D(
-               GL_TEXTURE_2D_ARRAY,
-               mip, 0, 0,
-               idx, mipWidth, mipHeight, 1,
-               GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], buf
-            );
-         }
-         glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
-         delete[] buf;
+         glTexSubImage3D(
+            GL_TEXTURE_2D_ARRAY,
+            mip, 0, 0,
+            slot, mipWidth, mipHeight, 1,
+            GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], buf
+         );
       }
+      delete[] buf;
    }
-
-   if (!isCompressed)
-      glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
-
-   // Clean temporary textures
-   for (GFXTexHandle handle : tmpHandles)
-   {
-      handle.free();
-   }
-
-   return success;
 }
 
 void GFXGLTextureArray::setToTexUnit(U32 tuNum)
@@ -179,13 +61,13 @@ void GFXGLTextureArray::setToTexUnit(U32 tuNum)
    dynamic_cast<GFXGLDevice*>(getOwningDevice())->setTextureArrayInternal(tuNum, this);
 }
 
-
 void GFXGLTextureArray::Release()
 {
    glDeleteTextures(1, &mTextureArray);
    mTextureArray = 0;
-}
 
+   GFXTextureArray::Release();
+}
 
 void GFXGLTextureArray::bind(U32 textureUnit) const
 {
@@ -201,7 +83,7 @@ void GFXGLTextureArray::bind(U32 textureUnit) const
    const GFXSamplerStateDesc& ssd = sb->getDesc().samplers[textureUnit];
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 0));
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]);
-   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mMin(mMipMapLevels - 1, 1));
+   glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mMin(mMipLevels - 1, 1));
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]);
 }

+ 7 - 4
Engine/source/gfx/gl/gfxGLTextureArray.h

@@ -11,9 +11,10 @@ class GFXGLTextureArray : public GFXTextureArray
 public:
    GFXGLTextureArray();
 
-   ~GFXGLTextureArray();
+   ~GFXGLTextureArray() { Release(); };
+
+   void init();
 
-   bool fromTextureArray(const Vector<GFXTexHandle>& textureArray) override;
    void setToTexUnit(U32 tuNum) override;
 
    void bind(U32 textureUnit) const;
@@ -23,11 +24,13 @@ public:
    void resurrect() override;
    void Release() override;
 
+protected:
+   void _setTexture(const GFXTexHandle& texture, U32 slot) override;
+
 private:
    GLuint mTextureArray;
 
-   U32 mMipMapLevels;
-   GFXFormat mFormat;
+   bool mIsCompressed;
 };