ID3D11ShaderResourceView* d3dHelper::CreateTexture2DArraySRV(
		ID3D11Device* device, ID3D11DeviceContext* context,
		std::vector<std::wstring>& filenames,
		DXGI_FORMAT format,
		UINT filter, 
		UINT mipFilter)
{
	//
	// Load the texture elements individually from file.  These textures
	// won't be used by the GPU (0 bind flags), they are just used to 
	// load the image data from file.  We use the STAGING usage so the
	// CPU can read the resource.
	//

	UINT size = filenames.size();

	std::vector<ID3D11Texture2D*> srcTex(size);
	for(UINT i = 0; i < size; ++i)
	{
		D3DX11_IMAGE_LOAD_INFO loadInfo;

        loadInfo.Width  = D3DX11_FROM_FILE;
        loadInfo.Height = D3DX11_FROM_FILE;
        loadInfo.Depth  = D3DX11_FROM_FILE;
        loadInfo.FirstMipLevel = 0;
        loadInfo.MipLevels = D3DX11_FROM_FILE;
        loadInfo.Usage = D3D11_USAGE_STAGING;
        loadInfo.BindFlags = 0;
        loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
        loadInfo.MiscFlags = 0;
        loadInfo.Format = format;
        loadInfo.Filter = filter;
        loadInfo.MipFilter = mipFilter;
		loadInfo.pSrcInfo  = 0;
		/*
		this is causing a linker error. God knows why... undo uncommet duncan help todo fix error
		*/
        HR(D3DX11CreateTextureFromFile(device, filenames[i].c_str(), 
			&loadInfo, 0, (ID3D11Resource**)&srcTex[i], 0));
		
	}

	//
	// Create the texture array.  Each element in the texture 
	// array has the same format/dimensions.
	//

	D3D11_TEXTURE2D_DESC texElementDesc;
	srcTex[0]->GetDesc(&texElementDesc);

	D3D11_TEXTURE2D_DESC texArrayDesc;
	texArrayDesc.Width              = texElementDesc.Width;
	texArrayDesc.Height             = texElementDesc.Height;
	texArrayDesc.MipLevels          = texElementDesc.MipLevels;
	texArrayDesc.ArraySize          = size;
	texArrayDesc.Format             = texElementDesc.Format;
	texArrayDesc.SampleDesc.Count   = 1;
	texArrayDesc.SampleDesc.Quality = 0;
	texArrayDesc.Usage              = D3D11_USAGE_DEFAULT;
	texArrayDesc.BindFlags          = D3D11_BIND_SHADER_RESOURCE;
	texArrayDesc.CPUAccessFlags     = 0;
	texArrayDesc.MiscFlags          = 0;

	ID3D11Texture2D* texArray = 0;
	HR(device->CreateTexture2D( &texArrayDesc, 0, &texArray));

	//
	// Copy individual texture elements into texture array.
	//

	// for each texture element...
	for(UINT texElement = 0; texElement < size; ++texElement)
	{
		// for each mipmap level...
		for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel)
		{
			D3D11_MAPPED_SUBRESOURCE mappedTex2D;
			HR(context->Map(srcTex[texElement], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D));

			context->UpdateSubresource(texArray, 
				D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels),
				0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch);

			context->Unmap(srcTex[texElement], mipLevel);
		}
	}	

	//
	// Create a resource view to the texture array.
	//
	
	D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
	viewDesc.Format = texArrayDesc.Format;
	viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
	viewDesc.Texture2DArray.MostDetailedMip = 0;
	viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels;
	viewDesc.Texture2DArray.FirstArraySlice = 0;
	viewDesc.Texture2DArray.ArraySize = size;

	ID3D11ShaderResourceView* texArraySRV = 0;
	HR(device->CreateShaderResourceView(texArray, &viewDesc, &texArraySRV));

	//
	// Cleanup--we only need the resource view.
	//

	ReleaseCOM(texArray);

	for(UINT i = 0; i < size; ++i)
		ReleaseCOM(srcTex[i]);

	return texArraySRV;
}
//===============================================================================================================================
ID3D11ShaderResourceView* TextureManager::CreateTexture2DArraySRV(std::vector<std::string>& filenames)
{
    //
    // Load the texture elements individually from file.  These textures
    // won't be used by the GPU (0 bind flags), they are just used to
    // load the image data from file.  We use the STAGING usage so the
    // CPU can read the resource.
    //

    UINT size = filenames.size();
    HRESULT result;

    std::vector<ID3D11Texture2D*> srcTex(size);

    for(UINT i = 0; i < size; ++i)
    {
        unique_ptr<wchar_t> name = BetterString(filenames[i].c_str()).ToWideStr();

        // ReleaseAndGetAddressOf
        result = CreateDDSTextureFromFileEx(mD3DSystem->GetDevice11(), name.get(), 0u, D3D11_USAGE_IMMUTABLE, D3D11_BIND_SHADER_RESOURCE, 0,//D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ,
                                            0, false, reinterpret_cast<ID3D11Resource**>(&srcTex[i]), nullptr, nullptr);

        if (FAILED(result))
        {
            return 0;
        }
    }

    //
    // Create the texture array.  Each element in the texture
    // array has the same format/dimensions.
    //

    D3D11_TEXTURE2D_DESC texElementDesc;
    srcTex[0]->GetDesc(&texElementDesc);

    /*
    	Usage: D3D11_USAGE_DEFAULT - Video RAM
    		   D3D11_USAGE_STAGING - in the system RAM and cannot be used by the GPU at all
    		   D3D11_USAGE_DYNAMIC - CPU- and GPU-addressable RAM
    		   D3D11_USAGE_IMMUTABLE
    */

    D3D11_TEXTURE2D_DESC texArrayDesc;
    texArrayDesc.Width              = texElementDesc.Width;
    texArrayDesc.Height             = texElementDesc.Height;
    texArrayDesc.MipLevels          = texElementDesc.MipLevels;
    texArrayDesc.ArraySize          = size;
    texArrayDesc.Format             = texElementDesc.Format;
    texArrayDesc.SampleDesc.Count   = 1;
    texArrayDesc.SampleDesc.Quality = 0;
    texArrayDesc.Usage				= D3D11_USAGE_DEFAULT;
    texArrayDesc.BindFlags          = D3D11_BIND_SHADER_RESOURCE;
    texArrayDesc.CPUAccessFlags		= 0;// D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
    texArrayDesc.MiscFlags          = 0;

    ID3D11Texture2D* texArray = 0;
    mD3DSystem->GetDevice11()->CreateTexture2D(&texArrayDesc, 0, &texArray);

    //
    // Copy individual texture elements into texture array.
    //

    // for each texture element...
    for(UINT texElement = 0; texElement < size; ++texElement)
    {
        // for each mipmap level...
        for(UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel)
        {
            mD3DSystem->GetDeviceContext()->CopySubresourceRegion(texArray, D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels), 0, 0, 0, srcTex[texElement], mipLevel, nullptr);
        }
    }

    // Release the temporary Video Memory used per texture
    for (UINT i = 0; i < size; ++i)
        SAFE_RELEASE(srcTex[i]);

    //
    // Create a resource view to the texture array.
    //

    D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
    viewDesc.Format = texArrayDesc.Format;
    viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
    viewDesc.Texture2DArray.MostDetailedMip = 0;
    viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels;
    viewDesc.Texture2DArray.FirstArraySlice = 0;
    viewDesc.Texture2DArray.ArraySize = size;

    ID3D11ShaderResourceView* texArraySRV = 0;
    mD3DSystem->GetDevice11()->CreateShaderResourceView(texArray, &viewDesc, &texArraySRV);

    //
    // Cleanup - we only need the resource view.
    //

    SAFE_RELEASE(texArray);

    // Return the new texture array
    return texArraySRV;
}
Beispiel #3
0
HRESULT ParticleSystem::CreateTexArray(const vector<string>& fileNames)
{
	HRESULT hr = S_OK;

	// Load the texture elements individually from file.  These textures
	// won't be used by the GPU (0 bind flags), they are just used to 
	// load the image data from file.  We use the STAGING usage so the
	// CPU can read the resource.
	this->mNrOfTextures = fileNames.size();

	vector<ID3D11Texture2D*> srcTex(this->mNrOfTextures, 0);
	for(UINT i = 0; i < this->mNrOfTextures; i++) 
	{
		D3DX11_IMAGE_LOAD_INFO loadInfo;

        loadInfo.Width  = D3DX11_FROM_FILE;
        loadInfo.Height = D3DX11_FROM_FILE;
        loadInfo.Depth  = D3DX11_FROM_FILE;
        loadInfo.FirstMipLevel = 0;
        loadInfo.MipLevels = D3DX11_FROM_FILE;
        loadInfo.Usage = D3D11_USAGE_STAGING;
        loadInfo.BindFlags = 0;
        loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
        loadInfo.MiscFlags = 0;
        loadInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        loadInfo.Filter = D3DX11_FILTER_NONE;
        loadInfo.MipFilter = D3DX11_FILTER_NONE;
		loadInfo.pSrcInfo  = 0;

		hr = D3DX11CreateTextureFromFile(this->gDevice, fileNames[i].c_str(), &loadInfo, 0, (ID3D11Resource**)&srcTex[i], 0);
		if(FAILED(hr))
		{
			MessageBox(0, "Couldn't load particle texture(s)", "Create texture from file error", MB_ICONERROR); 
			return hr;
		}
	}

	// Create the texture array.  Each element in the texture 
	// array has the same format/dimensions.
	D3D11_TEXTURE2D_DESC texElementDesc;
	srcTex[0]->GetDesc(&texElementDesc);

	D3D11_TEXTURE2D_DESC texArrayDesc;
	texArrayDesc.Width              = texElementDesc.Width;
	texArrayDesc.Height             = texElementDesc.Height;
	texArrayDesc.MipLevels          = texElementDesc.MipLevels;
	texArrayDesc.ArraySize          = this->mNrOfTextures; //nr of texture elements to store
	texArrayDesc.Format             = DXGI_FORMAT_R8G8B8A8_UNORM;
	texArrayDesc.SampleDesc.Count   = 1;
	texArrayDesc.SampleDesc.Quality = 0;
	texArrayDesc.Usage              = D3D11_USAGE_DEFAULT;
	texArrayDesc.BindFlags          = D3D11_BIND_SHADER_RESOURCE;
	texArrayDesc.CPUAccessFlags     = 0;
	texArrayDesc.MiscFlags          = 0;

	ID3D11Texture2D* texArray = 0;
	hr = this->gDevice->CreateTexture2D( &texArrayDesc, 0, &texArray);
	if(FAILED(hr))
	{
		MessageBox(0, "Couldn't create particle texture(s)", "Create texture2d error", MB_ICONERROR);
		return hr;
	}

	
	// Copy individual texture elements into texture array.
	// for each texture element...
	for(UINT i = 0; i < this->mNrOfTextures; i++)
	{
		// for each mipmap level...
		for(UINT j = 0; j < texElementDesc.MipLevels; ++j)
		{
			D3D11_MAPPED_SUBRESOURCE mappedSubres;
			UINT subResource = D3D11CalcSubresource(j, i, texElementDesc.MipLevels); //**samma för texarray?**
			//map
			this->gDeviceContext->Map(srcTex[i], subResource, D3D11_MAP_READ_WRITE, 0, &mappedSubres); //**write onödig?**
			//update
			this->gDeviceContext->UpdateSubresource(texArray, subResource, 0, mappedSubres.pData, mappedSubres.RowPitch, 0);
			//unmap
			this->gDeviceContext->Unmap(srcTex[i], subResource);

			/*D3D10:
			D3D10_MAPPED_TEXTURE2D mappedTex2D;
			srcTex[i]->Map(j, D3D10_MAP_READ, 0, &mappedTex2D);
			
            this->gDevice->UpdateSubresource(texArray, 
				D3D10CalcSubresource(j, i, texElementDesc.MipLevels),
                0, mappedTex2D.pData, mappedTex2D.RowPitch, 0);

            srcTex[i]->Unmap(j);*/
		}
	}

	// Create a resource view to the texture array.
	D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
	viewDesc.Format = texArrayDesc.Format;
	viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
	viewDesc.Texture2DArray.MostDetailedMip = 0;
	viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels;
	viewDesc.Texture2DArray.FirstArraySlice = 0;
	viewDesc.Texture2DArray.ArraySize = this->mNrOfTextures;

	hr = this->gDevice->CreateShaderResourceView(texArray, &viewDesc, &this->mTexArraySRV);

	// Cleanup--we only need the resource view.
	if ( texArray ) texArray->Release(), texArray=0;

	for(UINT i = 0; i < this->mNrOfTextures; i++)
	{
		if(srcTex[i])
		{
			srcTex[i]->Release();
		}
	}

	return hr;
}
void Texture::CreateTexture2DArray(
	ID3D11Device* d3dDevice,
	ID3D11DeviceContext* d3dDeviceContext,
	std::vector<std::wstring>& filenames,
	DXGI_FORMAT format,
	UINT filter,
	UINT mipFilter)
{
	if (nullptr != SRV)
	{
		MessageBox(0, L"[Texture::CreateTexture2DArraySRV] This View have been created!", 0, 0);
		assert(false);
	}
	//
	// 从文件加载单独的纹理元素。这些纹理不能被GPU使用(0 bind flags),
	// 只是用来从文件中加载图像数据。我们使用STAGING让CPU可以访问资源。
	//

	UINT size = filenames.size();

	std::vector<ID3D11Texture2D*> srcTex(size);
	for (UINT i = 0; i < size; ++i)
	{
		D3DX11_IMAGE_LOAD_INFO loadInfo;

		loadInfo.Width = D3DX11_FROM_FILE;
		loadInfo.Height = D3DX11_FROM_FILE;
		loadInfo.Depth = D3DX11_FROM_FILE;
		loadInfo.FirstMipLevel = 0;
		loadInfo.MipLevels = D3DX11_FROM_FILE;
		loadInfo.Usage = D3D11_USAGE_STAGING;
		loadInfo.BindFlags = 0;
		loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
		loadInfo.MiscFlags = 0;
		loadInfo.Format = format;
		loadInfo.Filter = filter;
		loadInfo.MipFilter = mipFilter;
		loadInfo.pSrcInfo = 0;

		HR(D3DX11CreateTextureFromFile(d3dDevice, filenames[i].c_str(),
			&loadInfo, 0, (ID3D11Resource**)&srcTex[i], 0));
	}

	//
	// 创建纹理数组。每个纹理元素都具有相同的格式/大小。
	//

	D3D11_TEXTURE2D_DESC texElementDesc;
	srcTex[0]->GetDesc(&texElementDesc);

	D3D11_TEXTURE2D_DESC texArrayDesc;
	texArrayDesc.Width = texElementDesc.Width;
	texArrayDesc.Height = texElementDesc.Height;
	texArrayDesc.MipLevels = texElementDesc.MipLevels;
	texArrayDesc.ArraySize = size;
	texArrayDesc.Format = texElementDesc.Format;
	texArrayDesc.SampleDesc.Count = 1;
	texArrayDesc.SampleDesc.Quality = 0;
	texArrayDesc.Usage = D3D11_USAGE_DEFAULT;
	texArrayDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	texArrayDesc.CPUAccessFlags = 0;
	texArrayDesc.MiscFlags = 0;

	ID3D11Texture2D* texArray = 0;
	HR(d3dDevice->CreateTexture2D(&texArrayDesc, 0, &texArray));

	//
	// 将单独的纹理元素复制到纹理数组中。
	//

	// 处理每个纹理元素...
	for (UINT texElement = 0; texElement < size; ++texElement)
	{
		// 处理每个渐进纹理层...
		for (UINT mipLevel = 0; mipLevel < texElementDesc.MipLevels; ++mipLevel)
		{
			D3D11_MAPPED_SUBRESOURCE mappedTex2D;
			HR(d3dDeviceContext->Map(srcTex[texElement], mipLevel, D3D11_MAP_READ, 0, &mappedTex2D));

			d3dDeviceContext->UpdateSubresource(texArray,
				D3D11CalcSubresource(mipLevel, texElement, texElementDesc.MipLevels),
				0, mappedTex2D.pData, mappedTex2D.RowPitch, mappedTex2D.DepthPitch);

			d3dDeviceContext->Unmap(srcTex[texElement], mipLevel);
		}
	}

	//
	// 创建纹理数组的资源视图
	//

	D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
	viewDesc.Format = texArrayDesc.Format;
	viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
	viewDesc.Texture2DArray.MostDetailedMip = 0;
	viewDesc.Texture2DArray.MipLevels = texArrayDesc.MipLevels;
	viewDesc.Texture2DArray.FirstArraySlice = 0;
	viewDesc.Texture2DArray.ArraySize = size;

	HR(d3dDevice->CreateShaderResourceView(texArray, &viewDesc, &SRV));

	//
	// 清除--我们要的只是资源视图
	//

	SafeRelease(texArray);

	for (UINT i = 0; i < size; ++i)
		SafeRelease(srcTex[i]);
}