Quantcast
Channel: GameDev.net
Viewing all articles
Browse latest Browse all 17560

Texture array with mipmaps

$
0
0

Hello, a while ago i started to use texture arrays for multitexturing in terrain shader. I didn't know how to load image files for texture array, so i used ID3D11DeviceContext::CopySubresourceRegion to populate texture array with textures loaded with WICTextureLoader.

That looks like this:

	D3D11_TEXTURE2D_DESC textureDesc;
	D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
	ZeroMemory(&shaderResourceViewDesc, sizeof(shaderResourceViewDesc));
	ZeroMemory(&textureDesc, sizeof(textureDesc));

	textureDesc.Width = TEX_PIXEL_SIZE;
	textureDesc.Height = TEX_PIXEL_SIZE;
	textureDesc.MipLevels = 1;
	textureDesc.ArraySize = v_texFName.size() + 1;
	textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	textureDesc.SampleDesc.Count = 1;
	textureDesc.Usage = D3D11_USAGE_DEFAULT;
	textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	textureDesc.CPUAccessFlags = 0;
	textureDesc.MiscFlags = 0;

	shaderResourceViewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
	shaderResourceViewDesc.Texture2DArray.MostDetailedMip = 0;
	shaderResourceViewDesc.Texture2DArray.MipLevels = 1;
	shaderResourceViewDesc.Texture2DArray.ArraySize = v_texFName.size() + 1;
	shaderResourceViewDesc.Texture2DArray.FirstArraySlice = 0;

	HRESULT hr;
	hr = pd3dDevice->CreateTexture2D(&textureDesc, 0, &pTextureArray);
	if (FAILED(hr))
		debugMsg("FAIL pTextureArray: %d", hr);
	hr = pd3dDevice->CreateShaderResourceView(pTextureArray, &shaderResourceViewDesc, &pTextureSRV);
	if (FAILED(hr))
		debugMsg("FAIL pTextureSRV: %d", hr);

	WCHAR wcharstr[260];
	ID3D11Resource *pNewTexture;
	for (UINT i = 0; i < v_texFName.size(); i++)
	{
		MultiByteToWideChar(CP_ACP, 0, v_texFName[i]->text, -1, wcharstr, 260);
		CreateWICTextureFromFile(pd3dDevice, wcharstr, &pNewTexture, 0);
		DXUTGetD3D11DeviceContext()->CopySubresourceRegion(pTextureArray, i, 0, 0, 0, pNewTexture, 0, 0);
		SAFE_RELEASE(pNewTexture);
	}

Now after reading some articles i noticed that WICTextureLoader can automatically generate mipmaps.

CreateWICTextureFromFileEx(pd3dDevice, pDeviceContext, wcharstr, 0,
	D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, 0,
	D3D11_RESOURCE_MISC_GENERATE_MIPS, false, &pNewTexture, 0);

But now i don't know how to copy these mipmapped textures into texture array.

According to some articles it should work like this:

    textureDesc.MipLevels = 0;
    textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
    textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

    shaderResourceViewDesc.Texture2DArray.MipLevels = -1;	

    // if texture has 9 mipmap levels
	for (UINT i = 0; i < v_texFName.size(); i++)
	{
		MultiByteToWideChar(CP_ACP, 0, v_texFName[i]->text, -1, wcharstr, 260);
		CreateWICTextureFromFileEx(pd3dDevice, DXUTGetD3D11DeviceContext(), wcharstr, 0,
			D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, 0,
			D3D11_RESOURCE_MISC_GENERATE_MIPS, false, &pNewTexture, 0);
		for (UINT j = 0; j < 9; j++)
			DXUTGetD3D11DeviceContext()->CopySubresourceRegion(pTextureArray, i * 9 + j, 0, 0, 0, pNewTexture, j, 0);
		SAFE_RELEASE(pNewTexture);
	}

But this doesn't seem to work. (it works only for the nearest mip level)

 

My questions are:

Why does a 256x256 px texture have 9 mip levels, and how do i get number of mip levels from a texture?

Why does the last code work only for the first mip level?

How do i populate a texture array with mipmapped textures?


Viewing all articles
Browse latest Browse all 17560

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>