Howdy,
So ive nearly finished my image libary for loading and converting textures, but im wonderingabout a more effecient way to get surface data.
These are the 2 storage methods that come to mind:
std::vector<std::vector<Byte> > mData;
Byte* mData;
Vector Pros:
-Can access any surface/mip easily:
Uint32 Image::GetSurfaceIndex(Uint32 face, Uint32 mipLevel)const
{
return (face * (mFileInfo.mArraySize - 1)) + mipLevel;
}
-No manually memory clean up etc.
Cons:
-Cannot load Blob data in single call, must run loop such as:
for (size_t f = 0; f < mFileInfo.mArraySize; f++)
{
Uint32 w = mFileInfo.mWidth;
Uint32 h = mFileInfo.mHeight;
for (size_t i = 0; i < mFileInfo.mMipCount; i++)
{
numBytes = GetSurfaceByteCount(w, h, mFileInfo.mSurfaceFormat);
std::vector<Byte> cpyData = std::vector<Byte>(data, data + numBytes);
mData[GetSurfaceIndex(f, i)] = cpyData;
}
if (src + numBytes > end)
{
Reset();
return;
}
src += numBytes;
w = SF::Max(w >> 1, 1);
h = SF::Max(h >> 1, 1);
}
Byte array Pros:
-Loading is simple:
mData = new Byte[mFileInfo.mByteCount];
memcpy(mData, ptr, mFileInfo.mByteCount);
Cons:
-Getting ptr to start of a surface becomes inefficient, especilaly with mips as it requires a loop.
Byte* Image::GetPixelPtr(Uint32 face, Uint32 mipLevel, Uint32 x, Uint32 y)
{
if (face > mFileInfo.mArraySize) { return nullptr; }
if (mipLevel > mFileInfo.mMipCount) { return nullptr; }
int w = mFileInfo.mWidth;
int h = mFileInfo.mHeight;
int mipBytes = 0;
for(int i = 1; i < mipLevel, i++)
{
w = SF::Max(w >> 1,1 );
h = SF::Max(h >> 1, 1);
mipBytes += GetSurfacebytes(w, h, mFileInfo.mSurfaceFormat);
}
return &mData[GetSurfaceOffset(face) + mipBytes + ((y * w) + x) * mPixelByteSize];
}
Note that GetSurfaceOffset() calculates the offset to the start of a surface, includeing the offset of the previous surfaces mips.
Does anyone know of a better way to store surface arrays with there mips in a single blob thats effecient to access?
Thanks