gfxTextureArray.cpp
Engine/source/gfx/gfxTextureArray.cpp
Detailed Description
1 2#include "gfxTextureArray.h" 3 4 5#include "gfxDevice.h" 6#include "gfxTextureManager.h" 7#include "bitmap/imageUtils.h" 8#include "console/console.h" 9 10GFXTextureArray::GFXTextureArray() 11 : mFormat(GFXFormat_COUNT), 12 mIsCompressed(false), 13 mWidth(0), 14 mHeight(0), 15 mArraySize(0), 16 mMipLevels(0) 17{ 18} 19 20void GFXTextureArray::set(U32 width, U32 height, U32 size, GFXFormat format, U32 mipLevels) 21{ 22 if (mipLevels == 0 && width == height && isPow2(width)) 23 { 24 mipLevels = mLog2(static_cast<F32>(width)) + 1; 25 } 26 if ( 27 mWidth == width && 28 mHeight == height && 29 mArraySize == size && 30 mFormat == format && 31 mMipLevels == mipLevels 32 ) 33 { 34 return; 35 } 36 37 Release(); 38 39 mWidth = width; 40 mHeight = height; 41 mArraySize = size; 42 mFormat = format; 43 mIsCompressed = ImageUtil::isCompressedFormat(mFormat); 44 mMipLevels = getMax(mipLevels, static_cast<U32>(1)); 45 46 mTextures.setSize(size); 47 48 init(); 49} 50 51bool GFXTextureArray::fromTextureArray(const Vector<GFXTexHandle>& textureArray, U32 capacity) 52{ 53 PROFILE_SCOPE(GFXTextureArray_fromTextureArray) 54 bool success = true; 55 56 // Not initialized, infer it from the given array of textures 57 if (mArraySize == 0) 58 { 59 bool found = false; 60 for (const GFXTexHandle& texObj : textureArray) 61 { 62 if (texObj.isValid()) 63 { 64 if (!found) 65 { 66 found = true; 67 mFormat = texObj.getFormat(); 68 mWidth = texObj.getWidth(); 69 mHeight = texObj.getHeight(); 70 mMipLevels = texObj->getMipLevels(); 71 } 72 73 if (mFormat != texObj.getFormat() || mWidth != texObj.getWidth() || mHeight != texObj.getHeight()) 74 { 75 AssertWarn(true, "GFXTextureArray::fromTextureArray there was a mismatch in texture formats, defaulting to uncompressed format"); 76 Con::warnf("GFXTextureArray::fromTextureArray there was a mismatch in texture formats, defaulting to uncompressed format"); 77 success = false; 78 mFormat = GFXFormatR8G8B8A8; 79 } 80 } 81 } 82 83 // One might think this should return false in this case, but the return value is mostly to highlight internal errors not input errors. 84 if (!found) return true; 85 86 87 //--------------------------------------------------------------------------------------- 88 // Create the texture array. Each element in the texture 89 // array has the same format/dimensions. 90 //--------------------------------------------------------------------------------------- 91 U32 size = capacity; 92 if (size == 0) 93 { 94 size = textureArray.size(); 95 } 96 set(mWidth, mHeight, size, mFormat, mMipLevels); 97 } 98 //--------------------------------------------------------------------------------------- 99 100 101 //--------------------------------------------------------------------------------------- 102 // Copy individual texture elements into texture array. 103 //--------------------------------------------------------------------------------------- 104 // for each texture element... 105 for (U32 i = 0; i < textureArray.size(); ++i) 106 { 107 if (textureArray[i].isValid()) 108 { 109 setTexture(textureArray[i], i); 110 } 111 } 112 //--------------------------------------------------------------------------------------- 113 114 return success; 115} 116 117void GFXTextureArray::setTexture(const GFXTexHandle& texture, U32 slot) 118{ 119 PROFILE_SCOPE(GFXTextureArray_setTexture) 120 GFXTexHandle handle = texture; 121 if (texture->getPath().isNotEmpty()) 122 { 123 if (texture.getHeight() != mHeight || texture.getWidth() != mWidth || texture.getFormat() != mFormat || texture->getMipLevels() < mMipLevels) 124 { 125 if (texture.getHeight() != mHeight || texture.getWidth() != mWidth) 126 { 127 AssertWarn(true, "GFXTextureArray::setTexture all textures should be the same size"); 128 Con::warnf("GFXTextureArray::setTexture all textures should be the same size"); 129 } 130 else if (texture->getMipLevels() < mMipLevels) 131 { 132 AssertWarn(true, "GFXTextureArray::setTexture all textures should have at least the same number of mips"); 133 Con::warnf("GFXTextureArray::setTexture all textures should have at least the same number of mips"); 134 } 135 else 136 { 137 AssertWarn(true, "GFXTextureArray::setTexture all textures should have the same format"); 138 Con::warnf("GFXTextureArray::setTexture all textures should have the same format"); 139 } 140 141 GBitmap* inBitmap = TEXMGR->loadUncompressedTexture(texture->getPath(), &GFXTexturePersistentProfile, mWidth, mHeight); 142 if (!inBitmap->setFormat(mFormat)) 143 { 144 AssertFatal(true, "GFXTextureArray::setTexture all textures must be convertible to GFXFormat " + mFormat); 145 Con::errorf("GFXTextureArray::setTexture all textures must be convertible to GFXFormat" + mFormat); 146 handle = NULL; 147 delete inBitmap; 148 } 149 else 150 { 151 handle = TEXMGR->createTexture(inBitmap, "", &GFXStaticTextureProfile, true); 152 } 153 } 154 } 155 if (!handle.isValid()) 156 { 157 return; 158 } 159 160 if (handle.getHeight() != mHeight || handle.getWidth() != mWidth || handle.getFormat() != mFormat || handle->getMipLevels() < mMipLevels) 161 { 162 AssertFatal(true, "GFXTextureArray::setTexture all textures must have the same size and format"); 163 Con::errorf("GFXTextureArray::setTexture all textures must have the same size and format"); 164 return; 165 } 166 167 mTextures[slot] = handle; 168 169 _setTexture(handle, slot); 170} 171 172void GFXTextureArray::Release() 173{ 174 for (GFXTexHandle& mTexture : mTextures) 175 { 176 mTexture = NULL; 177 } 178} 179 180const String GFXTextureArray::describeSelf() const 181{ 182 // We've got nothing 183 return String(); 184} 185