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; }
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]); }