i trying generate mipmap based on loading texture from file, but with large texture an exception: Access violation reading location.
D3DX11_IMAGE_LOAD_INFO ili;
ZeroMemory(&ili, sizeof(ili));
ili.BindFlags = 0;
ili.Height = D3DX11_FROM_FILE;
ili.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
ili.Width = D3DX11_FROM_FILE;
ili.Depth = D3DX11_FROM_FILE;
ili.FirstMipLevel = 0;
ili.MipLevels = 1;
ili.BindFlags = 0;
ili.CpuAccessFlags = D3D11_CPU_ACCESS_READ;
ili.Usage = D3D11_USAGE_STAGING;
ili.MiscFlags = 0;
ili.Filter = D3DX11_FILTER_NONE;
ili.MipFilter = D3DX11_FILTER_NONE;
ili.pSrcInfo = 0;
ID3D11Texture2D *pSrcText2D;
if(FAILED(D3DX11CreateTextureFromFile(g_pd3d11Device, L"1.jpg", &ili, NULL, (ID3D11Resource**)&pSrcText2D, NULL)))
return 0;
int numMipLevel = CreateMipMap(pSrcText2D);
D3D11_TEXTURE2D_DESC td;
pSrcText2D->GetDesc(&td);
ID3D11Texture2D *textArray = 0;
D3D11_TEXTURE2D_DESC tdArray;
ZeroMemory(&tdArray,sizeof(tdArray));
tdArray.ArraySize = numMipLevel+1;
tdArray.Format = td.Format;
tdArray.Height = td.Height;
tdArray.Width = td.Width;
tdArray.CPUAccessFlags = 0;
tdArray.MiscFlags = 0;
tdArray.SampleDesc.Count = 1;
tdArray.SampleDesc.Quality = 0;
tdArray.Usage = D3D11_USAGE_DEFAULT;
tdArray.BindFlags = D3D11_BIND_SHADER_RESOURCE;
tdArray.MipLevels = td.MipLevels;
if(FAILED(g_pd3d11Device->CreateTexture2D(&tdArray, NULL, &textArray)))
return 0;
//here there is an exception on second iteration
for(UINT i = 0; i <= numMipLevel; i++)
{
D3D11_MAPPED_SUBRESOURCE ms;
ZeroMemory(&ms, sizeof(ms));
if(FAILED(g_pd3d11DeviceContext->Map(g_pMassTextures[i], 0, D3D11_MAP_READ, 0, &ms)))
break;
g_pd3d11DeviceContext->UpdateSubresource(textArray, D3D11CalcSubresource(0, i, 1), 0, ms.pData, ms.RowPitch, ms.DepthPitch);
g_pd3d11DeviceContext->Unmap(g_pMassTextures[i], 0);
}
function generate Mipmap:
int CreateMipMap(ID3D11Texture2D *texture)
{
D3D11_TEXTURE2D_DESC td;
texture->GetDesc(&td);
UINT width = td.Width;
UINT height = td.Height;
float numMipLevel = (int)(log10((float)width)/log10((float)2));
if((int)(log10((float)height)/log10((float)2)) > numMipLevel)
numMipLevel = (int)log10((float)height)/log10((float)2);
g_pMassTextures.push_back(texture);
for(int i = 1; i <= numMipLevel; i++)
g_pMassTextures.push_back(CreateTexture2D(g_pd3d11Device, g_pMassTextures[i-1]));
return numMipLevel;
}
function create texture:
ID3D11Texture2D* CreateTexture2D(ID3D11Device *pDevice, ID3D11Texture2D *srcText)
{
D3D11_TEXTURE2D_DESC srcTD;
ZeroMemory(&srcTD, sizeof(srcTD));
srcText->GetDesc(&srcTD);
UINT width = srcTD.Width/2;
if(!width)
width = 1;
UINT height = srcTD.Height/2;
if(!height)
height = 1;
float stepU = srcTD.Width/(float)width;
float stepV = srcTD.Height/(float)height;
float sUV = stepU*stepV;
int sizeVBox = ceil(stepV);
int sizeUBox = ceil(stepU);
struct ColorTexels
{
XMCOLOR color;
float weight;
ColorTexels()
{
weight = 0;
}
};
ColorTexels **colorBox = new ColorTexels*[sizeVBox];
for(int i = 0; i < sizeVBox; i++)
colorBox[i] = new ColorTexels[sizeUBox];
XMCOLOR *dstBuffTexels = new XMCOLOR[width * height];
D3D11_MAPPED_SUBRESOURCE ms;
ZeroMemory(&ms, sizeof(ms));
if(FAILED(g_pd3d11DeviceContext->Map(srcText, 0, D3D11_MAP_READ, 0, &ms)))
return 0;
XMCOLOR *srcBuffTexels = new XMCOLOR[srcTD.Width * srcTD.Height];
memcpy(srcBuffTexels, ms.pData, ms.RowPitch * srcTD.Height);
g_pd3d11DeviceContext->Unmap(srcText, 0);
for(int i = 0; i < height; i++)
for(int j = 0; j < width; j++)
{
float bU = stepU * j;
float eU = bU + stepU;
float bV = stepV * i;
float eV = bV + stepV;
float sumU = bU, sumV = bV;
float sU, sV;
dstBuffTexels[width*i+j] = 0;
for(int k = 0; k < sizeVBox; k++)
{
for(int q = 0; q < sizeUBox; q++)
{
colorBox[k][q].color = srcBuffTexels[srcTD.Width*((int)bV+k) + (int)bU+q];
if((int)(bU+q) + 1 <= stepU + bU)
sU = (int)(bU+q) + 1 - sumU;
else
sU = eU - (int)eU;
if((int)(bV+k) + 1 <= stepV+ bV)
sV = (int)(bV+k) + 1 - sumV;
else
sV = eV - (int)eV;
sumU += sU;
colorBox[k][q].weight = (sU*sV)/sUV;
}
sumU = bU;
sumV += sV;
}
for(int e = 0; e < sizeVBox; e++)
for(int r = 0; r <sizeUBox; r++)
{
colorBox[e][r].color.b *= colorBox[e][r].weight;
colorBox[e][r].color.r *= colorBox[e][r].weight;
colorBox[e][r].color.g *= colorBox[e][r].weight;
dstBuffTexels[width*i+j] = dstBuffTexels[width*i+j] + colorBox[e][r].color;
}
}
delete []srcBuffTexels;
for(int i = 0; i < sizeVBox; i++)
delete []colorBox[i];
delete []colorBox;
ID3D11Texture2D *text = NULL;
D3D11_SUBRESOURCE_DATA sd;
ZeroMemory(&sd, sizeof(sd));
sd.pSysMem = (void*)dstBuffTexels;
sd.SysMemPitch = width*4;
sd.SysMemSlicePitch = width*height*4;
D3D11_TEXTURE2D_DESC td;
ZeroMemory(&td, sizeof(td));
td.Width = width;
td.Height = height;
td.MipLevels = 1;
td.ArraySize = 1;
td.SampleDesc.Count = 1;
td.SampleDesc.Quality = 0;
td.Usage = D3D11_USAGE_STAGING;
td.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
td.BindFlags = 0;
td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
td.MiscFlags = 0;
if(FAILED(pDevice->CreateTexture2D(&td, &sd, &text)))
{
delete []dstBuffTexels;
return 0;
}
else
{
delete []dstBuffTexels;
return text;
}
}