Directx11加载纹理

时间:2018-06-26 22:39:44

标签: c++ directx-11

d3d11中D3DXCreateTextureFromFileInMemory和D3DXCreateTextureFromFileEx的替代方法是什么?简单地说,如何将图像加载到纹理缓冲区(看起来像ID3D10Texture2D数据类型)以能够渲染它?

1 个答案:

答案 0 :(得分:1)

这是一个广泛的问题,但希望我能为您指明正确的方向。

在最高级别上,“加载”纹理涉及以下步骤:

  • 将图像数据以某种形式放入内存(从文件加载,通过算法生成等)。
  • 将图像数据转换为纹理所需的原始形式。这将取决于您所需的格式纹理。例如,大多数颜色(反照率)纹理将为DXGI_FORMAT_R8G8B8A8_UNORM_SRGB格式。此步骤可能涉及对源图像文件(例如,如果是JPEG或PNG)进行解压缩,并且如果格式采用不同的数据类型,则可能涉及某种形式的对话。
  • (可选)为纹理生成mip chain。通常,出于视觉和性能方面的考虑,完整的Mip链是一个好主意。
  • 将原始像素数据复制到纹理中。格式转换可以在此步骤中完成(这实际上取决于实现方式)。

对于转换部分,有很多库可以加载并将图像文件转换为原始像素数据。 Windows Imaging Component库(WIC)就是其中一种。还有其他地方-谷歌搜索将产生很多结果。

对于MIP生成,您可以自己执行此操作,或者某些第三方映像库将为您执行此操作。 D3DX也将生成mips。另一种选择是让D3D通过ID3D11DeviceContext::GenerateMips调用为您生成它们(不是理想的方法,但可以作为一个临时方法)。

顶部将原始像素数据复制到纹理中,假设它是静态(不变或“不变”的)数据,则应按以下方式创建纹理:

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调用来执行此操作(如果您偶尔要更改纹理内容,这将非常有用)。

这是对基础知识的粗略概述-网络上有大量的内容详细介绍了这些内容的工作方式和最佳做法等。我认为我可以推荐的最好的方法是找到一些内容示例代码并进行试验。

相关问题