So I just need to add first map as a copy of full source, then ? how do I create levels of it ?
Software Generating of Mip Maps
First level of mipmap pyramid is the source image you load - you can't mipmap it from the original image (as it has the same dimensions). You calculate only from there up.
My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com
Can you show me pseudocode or sample so that I can understand it myself or rewrite it ?
Can you help as always please ?
I'm quite in a hurry right now - but I'm using a code like this for CPU based mipmap generation (I removed some of additional features - they would only bring more confusion) - which generate mipmaps in place:
void LoaderDevIL::GenerateMipmaps(Image* image) const
{
// Calculate number of mipmaps
size_t dimLog2[2] = { 0 };
size_t width = image->mWidth;
size_t height = image->mHeight;
while (width > 1)
{
width /= 2;
dimLog2[0]++;
}
while (height > 1)
{
height /= 2;
dimLog2[1]++;
}
image->mMipLevels = dimLog2[0] > dimLog2[1] ? dimLog2[1] : dimLog2[0];
// Generate output buffer and fill in first layer (lowest mip level)
image->mMipmaps = new unsigned char*[image->mMipLevels];
image->mMipmaps[0] = image->mData;
// Build mip maps
width = image->mWidth;
height = image->mHeight;
for (size_t i = 1; i < image->mMipLevels; i++)
{
size_t newWidth = width / 2;
newWidth = newWidth == 0 ? 1 : newWidth;
size_t newHeight = height / 2;
newHeight = newHeight == 0 ? 1 : newHeight;
image->mMipmaps[i] = new unsigned char[newWidth * newHeight * 4];
for (size_t j = 0; j < newHeight; j++)
{
for (size_t k = 0; k < newWidth; k++)
{
size_t current = (k + j * newWidth) * image->mChannels;
size_t sample[4];
sample[0] = (k * 2 + j * 2 * width) * image->mChannels;
sample[1] = (k * 2 + 1 + j * 2 * width) * image->mChannels;
sample[2] = (k * 2 + (j * 2 + 1) * width) * image->mChannels;
sample[3] = (k * 2 + 1 + (j * 2 + 1) * width) * image->mChannels;
unsigned int sum[4];
sum[0] = (unsigned int)(image->mMipmaps[i - 1][sample[0] + 0]) +
(unsigned int)(image->mMipmaps[i - 1][sample[1] + 0]) +
(unsigned int)(image->mMipmaps[i - 1][sample[2] + 0]) +
(unsigned int)(image->mMipmaps[i - 1][sample[3] + 0]);
sum[1] = (unsigned int)(image->mMipmaps[i - 1][sample[0] + 1]) +
(unsigned int)(image->mMipmaps[i - 1][sample[1] + 1]) +
(unsigned int)(image->mMipmaps[i - 1][sample[2] + 1]) +
(unsigned int)(image->mMipmaps[i - 1][sample[3] + 1]);
sum[2] = (unsigned int)(image->mMipmaps[i - 1][sample[0] + 2]) +
(unsigned int)(image->mMipmaps[i - 1][sample[1] + 2]) +
(unsigned int)(image->mMipmaps[i - 1][sample[2] + 2]) +
(unsigned int)(image->mMipmaps[i - 1][sample[3] + 2]);
sum[3] = (unsigned int)(image->mMipmaps[i - 1][sample[0] + 3]) +
(unsigned int)(image->mMipmaps[i - 1][sample[1] + 3]) +
(unsigned int)(image->mMipmaps[i - 1][sample[2] + 3]) +
(unsigned int)(image->mMipmaps[i - 1][sample[3] + 3]);
sum[0] /= 4;
sum[1] /= 4;
sum[2] /= 4;
sum[3] /= 4;
image->mMipmaps[i][current + 0] = sum[0];
image->mMipmaps[i][current + 1] = sum[1];
image->mMipmaps[i][current + 2] = sum[2];
image->mMipmaps[i][current + 3] = sum[3];
}
}
width = newWidth;
height = newHeight;
}
}
And Image struct will resemble something like this:
struct Image
{
...
size_t mWidth;
size_t mHeight;
size_t mBpp;
size_t mChannels;
size_t mMipLevels;
unsigned char* mData;
unsigned char** mMipmaps;
...
};
Keep in mind that mBpp is BYTES per pixel, not bits. Width, height and channels are obvious. mMipLevels holds how many miplevels you have. mData points to memory holding bottom-most mip level in mipmap pyramid (i.e. the largest image), and mMipmaps holds mMipLevels count of pointers - each representing single mip level in mipmap pyramid (the one at index 0 should be the same as mData - i.e. the original image).
My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com
Thanks so much <3 !
I see that mBPP is not used at all ? and the above code is ported, but still crashes
One more question
image->mMipmaps[i] = new unsigned char[newWidth * newHeight * 4];
is 4 BPP ?
number of channgels is RGB ? or RGBA ? or RG ..etc ?
it works perfect with 32bits..I have images that are 16bits also, 64 bits .. how do I fix that ?
AhmedSaleh said:
mage->mMipmaps[i] = new unsigned char[newWidth * newHeight * 4]; is 4 BPP ? number of channgels is RGB ? or RGBA ? or RG ..etc ?
What's your analysis?
fixed everything Many thanks @vilem otte