Directx11 加载纹理
Directx11 loading texture
d3d11 中的 D3DXCreateTextureFromFileInMemory 和 D3DXCreateTextureFromFileEx 有什么替代方案?我怎样才能将图像加载到纹理缓冲区(看起来像 ID3D10Texture2D 数据类型)以便能够渲染它?
这是一个广泛的问题,但希望我能帮助您指明正确的方向。
在最高级别,"loading"纹理涉及以下步骤:
- 将图像数据以某种形式放入内存(从文件加载、算法生成等)。
- 将图像数据转换为纹理所需的原始格式。这将取决于您需要的格式纹理。例如,大多数颜色(反照率)纹理将采用
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
格式。此步骤可能涉及源图像文件的解压缩(例如,如果它是 JPEG 或 PNG),如果格式采用不同的数据类型等,则可能涉及某种形式的对话。
- (可选)为纹理生成 mip chain。通常,出于视觉和性能原因,拥有完整的 mip 链是个好主意。
- 将原始像素数据复制到纹理中。格式转换可以在此步骤中完成(具体取决于实现)。
对于转换部分,有很多库可以加载图像文件并将其转换为原始像素数据。 Windows Imaging Component 库 (WIC) 就是其中之一。还有其他的 - google 搜索会产生很多结果。
对于 MIP 生成,您可以自己执行此操作,或者某些第三方图像库会为您执行此操作。 D3DX 也会生成 mip。另一种选择是让 D3D 通过 ID3D11DeviceContext::GenerateMips
调用为您生成它们(不理想,但可以作为权宜之计)。
顶部将原始像素数据复制到纹理中,假设它是静态(不变,或 "immutable")数据,您应该像这样创建纹理:
D3D11_TEXTURE2D_DESC tdesc;
// ...
// Fill out width, height, mip levels, format, etc...
// ...
tdesc.Usage = D3D11_USAGE_IMMUTABLE;
tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // Add D3D11_BIND_RENDER_TARGET if you want to go
// with the auto-generate mips route.
tdesc.CPUAccessFlags = 0;
tdesc.MiscFlags = 0; // or D3D11_RESOURCE_MISC_GENERATE_MIPS for auto-mip gen.
D3D11_SUBRESOURCE_DATA srd; // (or an array of these if you have more than one mip level)
srd.pSysMem = pointer_to_raw_pixel_data; // This data should be in raw pixel format
srd.SysMemPitch = width_of_row_in_bytes; // Sometimes pixel rows may be padded so this might not be as simple as width * pixel_size_in_bytes.
srd.SysMemSlicePitch = 0;
ID3D11Texture2D * texture;
pDevice->CreateTexture2D(&tdesc, &srd, &texture);
这将一次性创建纹理并用您的像素数据填充它。您还可以使用 D3D11_USAGE_DEFAULT 使用标志创建纹理,并在创建后使用 ID3D11DeviceContext::Map/Unmap 调用来执行此操作(如果您偶尔更改纹理内容,这很有用)。
这是对基础知识的粗略概述 - 网上有大量内容详细介绍了所有这些内容的工作原理和最佳实践等。我认为我可以推荐的最好的东西是找到一些示例代码并进行试验。
d3d11 中的 D3DXCreateTextureFromFileInMemory 和 D3DXCreateTextureFromFileEx 有什么替代方案?我怎样才能将图像加载到纹理缓冲区(看起来像 ID3D10Texture2D 数据类型)以便能够渲染它?
这是一个广泛的问题,但希望我能帮助您指明正确的方向。
在最高级别,"loading"纹理涉及以下步骤:
- 将图像数据以某种形式放入内存(从文件加载、算法生成等)。
- 将图像数据转换为纹理所需的原始格式。这将取决于您需要的格式纹理。例如,大多数颜色(反照率)纹理将采用
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
格式。此步骤可能涉及源图像文件的解压缩(例如,如果它是 JPEG 或 PNG),如果格式采用不同的数据类型等,则可能涉及某种形式的对话。 - (可选)为纹理生成 mip chain。通常,出于视觉和性能原因,拥有完整的 mip 链是个好主意。
- 将原始像素数据复制到纹理中。格式转换可以在此步骤中完成(具体取决于实现)。
对于转换部分,有很多库可以加载图像文件并将其转换为原始像素数据。 Windows Imaging Component 库 (WIC) 就是其中之一。还有其他的 - google 搜索会产生很多结果。
对于 MIP 生成,您可以自己执行此操作,或者某些第三方图像库会为您执行此操作。 D3DX 也会生成 mip。另一种选择是让 D3D 通过 ID3D11DeviceContext::GenerateMips
调用为您生成它们(不理想,但可以作为权宜之计)。
顶部将原始像素数据复制到纹理中,假设它是静态(不变,或 "immutable")数据,您应该像这样创建纹理:
D3D11_TEXTURE2D_DESC tdesc;
// ...
// Fill out width, height, mip levels, format, etc...
// ...
tdesc.Usage = D3D11_USAGE_IMMUTABLE;
tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // Add D3D11_BIND_RENDER_TARGET if you want to go
// with the auto-generate mips route.
tdesc.CPUAccessFlags = 0;
tdesc.MiscFlags = 0; // or D3D11_RESOURCE_MISC_GENERATE_MIPS for auto-mip gen.
D3D11_SUBRESOURCE_DATA srd; // (or an array of these if you have more than one mip level)
srd.pSysMem = pointer_to_raw_pixel_data; // This data should be in raw pixel format
srd.SysMemPitch = width_of_row_in_bytes; // Sometimes pixel rows may be padded so this might not be as simple as width * pixel_size_in_bytes.
srd.SysMemSlicePitch = 0;
ID3D11Texture2D * texture;
pDevice->CreateTexture2D(&tdesc, &srd, &texture);
这将一次性创建纹理并用您的像素数据填充它。您还可以使用 D3D11_USAGE_DEFAULT 使用标志创建纹理,并在创建后使用 ID3D11DeviceContext::Map/Unmap 调用来执行此操作(如果您偶尔更改纹理内容,这很有用)。
这是对基础知识的粗略概述 - 网上有大量内容详细介绍了所有这些内容的工作原理和最佳实践等。我认为我可以推荐的最好的东西是找到一些示例代码并进行试验。