d3d12 图像超过功能级别最大纹理使用纹理数组代码
时间: 2024-03-27 09:35:26 浏览: 139
DirectX12(D3D12) 基础学习笔记及代码示例
5星 · 资源好评率100%
以下是使用纹理数组的示例代码:
首先,需要创建一个 D3D12_TEXTURE2D_DESC 结构体来描述纹理数组的属性,例如纹理的宽度、高度、格式等等:
```
D3D12_TEXTURE2D_DESC texArrayDesc = {};
texArrayDesc.Width = 1024;
texArrayDesc.Height = 1024;
texArrayDesc.MipLevels = 1;
texArrayDesc.ArraySize = 3; // 纹理数组的大小
texArrayDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texArrayDesc.SampleDesc.Count = 1;
texArrayDesc.SampleDesc.Quality = 0;
texArrayDesc.Usage = D3D12_USAGE_DEFAULT;
texArrayDesc.BindFlags = D3D12_BIND_SHADER_RESOURCE;
texArrayDesc.CPUAccessFlags = 0;
texArrayDesc.MiscFlags = D3D12_RESOURCE_MISC_TEXTURECUBE;
```
然后,需要创建一个纹理数组资源:
```
ComPtr<ID3D12Resource> texArray = nullptr;
ThrowIfFailed(device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
&texArrayDesc,
D3D12_RESOURCE_STATE_COMMON,
nullptr,
IID_PPV_ARGS(&texArray)));
```
接下来,需要为纹理数组资源创建一个 SRV 描述符堆:
```
D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
srvHeapDesc.NumDescriptors = 1; // 只有一个纹理数组
srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
ThrowIfFailed(device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&srvHeap)));
CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(srvHeap->GetCPUDescriptorHandleForHeapStart());
CD3DX12_GPU_DESCRIPTOR_HANDLE srvGpuHandle(srvHeap->GetGPUDescriptorHandleForHeapStart());
// 创建 SRV 描述符
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = texArrayDesc.Format;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.ArraySize = texArrayDesc.ArraySize; // 数组大小
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.PlaneSlice = 0;
srvDesc.Texture2DArray.ResourceMinLODClamp = 0.0f;
device->CreateShaderResourceView(texArray.Get(), &srvDesc, srvHandle);
```
最后,需要将纹理数据复制到纹理数组中:
```
// 将纹理数据复制到纹理数组的第 0 个元素中
D3D12_SUBRESOURCE_DATA texArrayData[3] = {};
for (int i = 0; i < 3; ++i)
{
texArrayData[i].pData = ...; // 纹理数据
texArrayData[i].RowPitch = ...;
texArrayData[i].SlicePitch = ...;
}
UpdateSubresources(commandList.Get(), texArray.Get(), texArrayUpload.Get(), 0, 0, 3, texArrayData);
// 将资源状态从 COMMON 转换为 SHADER_RESOURCE
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
texArray.Get(),
D3D12_RESOURCE_STATE_COMMON,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
commandList->ResourceBarrier(1, &barrier);
```
现在,纹理数组就可以在着色器中使用了。例如,在 HLSL 中可以这样定义一个纹理数组:
```
Texture2DArray<float4> g_TexArray : register(t0);
```
在着色器中使用时,可以通过数组下标来访问不同的纹理:
```
float4 texel = g_TexArray.Sample(texSampler, float3(texU, texV, texIndex));
```
阅读全文