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

DirectX11纹理映射失败0x80070057:动态纹理像素修改问题

问题分析与解决方案

核心问题1:纹理指针过早释放

你的SetDevice函数中创建纹理后立即调用了pTexture->Release(),导致pTexture变为无效悬空指针。后续调用DrawPoint时,使用这个无效指针调用Map必然失败,错误码0x80070057(E_INVALIDARG,无效参数)正是因为传入了已释放的资源。

修复步骤:

  1. 删除SetDevice中的pTexture->Release()语句:
GGUI::pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &my_texture);
// pTexture->Release(); // 移除这一行
stbi_image_free(image_data);
  1. 在ImageR类的析构函数中统一释放资源,确保纹理在整个实例生命周期内有效:
ImageR::~ImageR()
{
    if (pTexture)
        pTexture->Release();
    if (my_texture)
        my_texture->Release();
    // 释放其他相关资源(如fileinmem等)
}

核心问题2:动态纹理Map标志位错误

对于D3D11_USAGE_DYNAMIC类型且CPUAccessFlags = D3D11_CPU_ACCESS_WRITE的纹理,DirectX 11规定只能使用以下两个Map标志:

  • D3D11_MAP_WRITE_DISCARD:丢弃原有纹理内容,CPU写入新数据(适合完全更新或局部覆盖)
  • D3D11_MAP_WRITE_NO_OVERWRITE:CPU写入未被GPU使用的区域(适合追加更新)

你之前使用的D3D11_MAP_WRITE不支持动态纹理,这也是Map失败的原因之一。

修复步骤:

修改DrawPoint中的Map调用,使用正确的标志位:

HRESULT hr = GGUI::pd3dDeviceContext->Map(pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);

额外问题:像素坐标计算与颜色传递错误

  1. RowPitch对齐问题:纹理的行字节数(mappedResource.RowPitch)可能因GPU内存对齐要求,不等于宽度*4,直接用UIW*4计算像素位置会导致偏移错误。需要将RowPitch传入_DrawPoint函数。
  2. 颜色参数未利用:你传入了newColor但_DrawPoint硬编码了白色,需要将newColor转换为ImVec4传入。

修复代码:

修改DrawPoint中_DrawPoint的调用:

// 将newColor分解为RGBA分量(对应R8G8B8A8格式)
ImVec4 color(
    (newColor >> 16) & 0xFF,  // R
    (newColor >> 8) & 0xFF,   // G
    newColor & 0xFF,          // B
    (newColor >> 24) & 0xFF   // A
);
_DrawPoint((unsigned char*)mappedResource.pData, mappedResource.RowPitch, ImVec2(x, y), ImVec2(width, height), 5, color);

修改_DrawPoint的签名和实现:

void ImageR::_DrawPoint(unsigned char* data, UINT rowPitch, ImVec2 pos, ImVec2 size, int radius, ImVec4 color)
{
    int px = (int)pos.x;
    int py = (int)pos.y;
    int texWidth = (int)size.x;
    int texHeight = (int)size.y;

    // 坐标边界检查
    if (px < 0 || px >= texWidth || py < 0 || py >= texHeight)
        return;

    // 计算目标像素地址
    unsigned char* pixel = data + py * rowPitch + px * 4;
    pixel[0] = (unsigned char)color.x; // R
    pixel[1] = (unsigned char)color.y; // G
    pixel[2] = (unsigned char)color.z; // B
    pixel[3] = (unsigned char)color.w; // A

    // 如果需要绘制带半径的点,补充遍历半径内像素的逻辑
}

验证修复效果

完成上述修改后:

  1. pTexture保持有效,Map时不会再触发无效参数错误
  2. 使用D3D11_MAP_WRITE_DISCARD符合动态纹理的CPU访问规则,能正确映射纹理内存
  3. 像素位置计算和颜色传递正确,修改后的纹理能正常渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 00:44:52