You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用DirectX11结合DirectXTex与WICTextureLoader渲染动态GIF

DirectX11 渲染动态GIF/多帧图流程提示

首先明确:LoadFromWICFile加载多帧文件(比如GIF、TIF)时,ScratchImage会把所有帧以数组纹理的形式存储(每帧对应数组的一个元素)。你需要正确提取或利用这些帧数据,再配合渲染循环切换帧来实现动态效果。

1. 确认多帧数据信息

加载成功后,通过info结构体就能拿到关键信息:

// 获取总帧数
UINT totalFrames = info.ArraySize;
// 每帧的尺寸、像素格式和info里的Width/Height/Format一致(多帧图一般尺寸统一)

2. 创建支持多帧的着色器资源视图(SRV)

别用CreateWICTextureFromMemory(它是给单帧内存数据用的快捷方法),直接从ScratchImage创建数组纹理的SRV:

ID3D11Texture2D* texture = nullptr;
// 从ScratchImage的首帧数据创建纹理(因为多帧是数组结构,首帧就能关联所有帧)
HRESULT hr = image->GetImage(0, 0, 0)->CreateTexture(d3dDev, &texture);
if (FAILED(hr)) { /* 这里写错误处理逻辑 */ }

// 配置SRV描述,明确是纹理数组
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = info.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.MipLevels = info.MipLevels;
srvDesc.Texture2DArray.ArraySize = totalFrames;
srvDesc.Texture2DArray.FirstArraySlice = 0;

ID3D11ShaderResourceView* imgtextureView = nullptr;
hr = d3dDev->CreateShaderResourceView(texture, &srvDesc, &imgtextureView);
texture->Release(); // SRV创建好后,原纹理可以释放
if (FAILED(hr)) { /* 错误处理 */ }

3. 在渲染循环中切换帧

动态效果的核心是定时切换要渲染的帧索引:

  • 如果你的bitblt函数支持纹理数组采样,直接把当前帧索引(比如currentFrame,从0到totalFrames-1循环)传给它就行
  • 如果是自定义着色器,要在常量缓冲区里传递currentFrame,然后在像素着色器里用Texture2DArray.Sample(sampler, uv, currentFrame)来采样对应帧的像素

4. 处理GIF的帧延迟(可选但重要)

GIF每帧自带延迟时间,要实现准确的播放速度,得读取这个延迟值。如果嫌麻烦,也可以用固定间隔切换,示例:

static DWORD lastSwitchTime = GetTickCount();
DWORD now = GetTickCount();
// 每100ms切换一帧(可根据实际需求调整)
if (now - lastSwitchTime > 100) {
    currentFrame = (currentFrame + 1) % totalFrames;
    lastSwitchTime = now;
}

原代码的问题修正

你原代码里用CreateWICTextureFromMemory是错误的,因为ScratchImage已经加载好所有帧的像素数据,直接基于它创建纹理和SRV就可以,不需要再转成内存数据重新用WIC加载。

内容的提问来源于stack exchange,提问作者locodog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:53:31