diff --git a/Engine/source/gfx/D3D11/gfxD3D11TextureArray.cpp b/Engine/source/gfx/D3D11/gfxD3D11TextureArray.cpp index 13a4489be..6a6d2f019 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11TextureArray.cpp +++ b/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 &textureArray) +void GFXD3D11TextureArray::init() { - bool success = true; - Vector texture2Ds; - texture2Ds.setSize(textureArray.size()); - Vector tmpHandles; - - 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(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(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(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(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!"); - //--------------------------------------------------------------------------------------- - - - //--------------------------------------------------------------------------------------- - // Copy individual texture elements into texture array. - //--------------------------------------------------------------------------------------- - // 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) - { - handle.free(); - } - //--------------------------------------------------------------------------------------- + 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!"); //--------------------------------------------------------------------------------------- // Create a resource view to the texture array. //--------------------------------------------------------------------------------------- - createResourceView(texArrayDesc.Format, texArrayDesc.MipLevels, texArrayDesc.BindFlags); + createResourceView(mTextureArrayDesc.Format, mTextureArrayDesc.MipLevels, mTextureArrayDesc.BindFlags); //--------------------------------------------------------------------------------------- +} - return success; +void GFXD3D11TextureArray::_setTexture(const GFXTexHandle& texture, U32 slot) +{ + GFXD3D11TextureObject *texObj = dynamic_cast(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) + { + 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); + } } 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() diff --git a/Engine/source/gfx/D3D11/gfxD3D11TextureArray.h b/Engine/source/gfx/D3D11/gfxD3D11TextureArray.h index abeac3b59..be7851d75 100644 --- a/Engine/source/gfx/D3D11/gfxD3D11TextureArray.h +++ b/Engine/source/gfx/D3D11/gfxD3D11TextureArray.h @@ -20,7 +20,9 @@ public: { } - bool fromTextureArray(const Vector &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; }; diff --git a/Engine/source/gfx/Null/gfxNullDevice.cpp b/Engine/source/gfx/Null/gfxNullDevice.cpp index 98c61ecae..92e688a48 100644 --- a/Engine/source/gfx/Null/gfxNullDevice.cpp +++ b/Engine/source/gfx/Null/gfxNullDevice.cpp @@ -184,8 +184,11 @@ public: void zombify() override {} void resurrect() override {} void Release() override {} - bool fromTextureArray(const Vector &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 diff --git a/Engine/source/gfx/gfxTextureArray.cpp b/Engine/source/gfx/gfxTextureArray.cpp index e1458e908..e7f3797ab 100644 --- a/Engine/source/gfx/gfxTextureArray.cpp +++ b/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& 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 diff --git a/Engine/source/gfx/gfxTextureArray.h b/Engine/source/gfx/gfxTextureArray.h index 72c95995b..48067c3e1 100644 --- a/Engine/source/gfx/gfxTextureArray.h +++ b/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 &textureArray) = 0; + virtual void init() = 0; + virtual void set(U32 width, U32 height, U32 size, GFXFormat format, U32 mipLevels); + virtual bool fromTextureArray(const Vector &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 mTextures; + +protected: + virtual void _setTexture(const GFXTexHandle& texture, U32 slot) = 0; }; diff --git a/Engine/source/gfx/gl/gfxGLTextureArray.cpp b/Engine/source/gfx/gl/gfxGLTextureArray.cpp index 72d9a6875..cc19fff5d 100644 --- a/Engine/source/gfx/gl/gfxGLTextureArray.cpp +++ b/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() +void GFXGLTextureArray::init() { - glDeleteTextures(1, &mTextureArray); -} - -bool GFXGLTextureArray::fromTextureArray(const Vector &textureArray) -{ - 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 texture2Ds; - texture2Ds.setSize(textureArray.size()); - Vector 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(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(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(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]); } diff --git a/Engine/source/gfx/gl/gfxGLTextureArray.h b/Engine/source/gfx/gl/gfxGLTextureArray.h index 7730f1257..0134a050c 100644 --- a/Engine/source/gfx/gl/gfxGLTextureArray.h +++ b/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& 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; };