Torque3D/Engine/source/gfx/gfxTextureArray.cpp

184 lines
6 KiB
C++
Raw Normal View History

2021-01-01 20:05:21 +00:00
#include "gfxTextureArray.h"
2021-01-01 20:05:11 +00:00
#include "gfxDevice.h"
#include "gfxTextureManager.h"
2021-01-02 01:08:22 +00:00
#include "bitmap/imageUtils.h"
2021-01-01 20:05:11 +00:00
#include "console/console.h"
GFXTextureArray::GFXTextureArray()
: mFormat(GFXFormat_COUNT),
mIsCompressed(false),
mWidth(0),
mHeight(0),
mArraySize(0),
mMipLevels(0)
{
}
2021-01-01 20:05:11 +00:00
void GFXTextureArray::set(U32 width, U32 height, U32 size, GFXFormat format, U32 mipLevels)
{
if (mipLevels == 0 && width == height && isPow2(width))
{
mipLevels = mLog2(static_cast<F32>(width)) + 1;
}
if (
mWidth == width &&
mHeight == height &&
mArraySize == size &&
mFormat == format &&
mMipLevels == mipLevels
)
{
return;
}
Release();
2021-01-01 20:05:11 +00:00
mWidth = width;
mHeight = height;
mArraySize = size;
mFormat = format;
2021-01-02 01:08:22 +00:00
mIsCompressed = ImageUtil::isCompressedFormat(mFormat);
mMipLevels = getMax(mipLevels, static_cast<U32>(1));
2021-01-01 20:05:11 +00:00
mTextures.setSize(size);
init();
}
bool GFXTextureArray::fromTextureArray(const Vector<GFXTexHandle>& textureArray, U32 capacity)
2021-01-01 20:05:11 +00:00
{
PROFILE_SCOPE(GFXTextureArray_fromTextureArray)
2021-01-01 20:05:11 +00:00
bool success = true;
// Not initialized, infer it from the given array of textures
if (mArraySize == 0)
2021-01-01 20:05:11 +00:00
{
bool found = false;
for (const GFXTexHandle& texObj : textureArray)
2021-01-01 20:05:11 +00:00
{
if (texObj.isValid())
2021-01-01 20:05:11 +00:00
{
if (!found)
{
found = true;
mFormat = texObj.getFormat();
mWidth = texObj.getWidth();
mHeight = texObj.getHeight();
mMipLevels = texObj->getMipLevels();
}
2021-01-01 20:05:11 +00:00
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;
}
2021-01-01 20:05:11 +00:00
}
}
// 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;
2021-01-01 20:05:11 +00:00
//---------------------------------------------------------------------------------------
// Create the texture array. Each element in the texture
// array has the same format/dimensions.
//---------------------------------------------------------------------------------------
U32 size = capacity;
if (size == 0)
{
size = textureArray.size();
}
set(mWidth, mHeight, size, mFormat, mMipLevels);
}
2021-01-01 20:05:11 +00:00
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// Copy individual texture elements into texture array.
//---------------------------------------------------------------------------------------
// for each texture element...
for (U32 i = 0; i < textureArray.size(); ++i)
2021-01-01 20:05:11 +00:00
{
if (textureArray[i].isValid())
{
setTexture(textureArray[i], i);
}
}
//---------------------------------------------------------------------------------------
return success;
}
void GFXTextureArray::setTexture(const GFXTexHandle& texture, U32 slot)
{
PROFILE_SCOPE(GFXTextureArray_setTexture)
2021-01-01 20:05:11 +00:00
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, avar("GFXTextureArray::setTexture all textures should be the same size: %i vs %i", texture.getHeight(), mHeight));
Con::warnf(avar("GFXTextureArray::setTexture all textures should be the same size: %i vs %i", texture.getHeight(), mHeight));
2021-01-01 20:05:11 +00:00
}
else if (texture->getMipLevels() < mMipLevels)
{
AssertWarn(true, avar("GFXTextureArray::setTexture all textures should have at least the same number of mips: %i vs %i", texture->getMipLevels(), mMipLevels));
Con::warnf(avar("GFXTextureArray::setTexture all textures should have at least the same number of mips: %i vs %i", texture->getMipLevels(), mMipLevels));
2021-01-01 20:05:11 +00:00
}
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))
{
AssertFatal(true, "GFXTextureArray::setTexture all textures must be convertible to GFXFormat " + mFormat);
2021-01-01 20:05:11 +00:00
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)
{
AssertFatal(true, "GFXTextureArray::setTexture all textures must have the same size and format");
2021-01-01 20:05:11 +00:00
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;
}
}
2021-01-01 20:05:21 +00:00
const String GFXTextureArray::describeSelf() const
{
// We've got nothing
return String();
}