【问题标题】:DX11 convert pixel format BGRA to RGBADX11 将像素格式 BGRA 转换为 RGBA
【发布时间】:2014-06-16 23:27:24
【问题描述】:

我目前遇到的问题是库创建具有 BGRA 像素格式的 DX11 纹理。 但是显示库只能正确显示RGBA。 (这意味着颜色在渲染图像中被交换)

环顾四周后,我发现了一个简单的 for 循环来解决问题,但性能不是很好,并且随着分辨率的提高而扩展不好。我是 DirectX 的新手,也许我只是错过了一个简单的函数来进行转换。

// Get the image data
unsigned char* pDest = view->image->getPixels();

// Prepare source texture
ID3D11Texture2D* pTexture = static_cast<ID3D11Texture2D*>( tex );

// Get context
ID3D11DeviceContext* pContext = NULL;
dxDevice11->GetImmediateContext(&pContext);

// Copy data, fast operation
pContext->CopySubresourceRegion(texStaging, 0, 0, 0, 0, tex, 0, nullptr);

// Create mapping 
D3D11_MAPPED_SUBRESOURCE mapped;
HRESULT hr = pContext->Map( texStaging, 0, D3D11_MAP_READ, 0, &mapped );

if ( FAILED( hr ) )
{
    return;
}

// Calculate size
const size_t size = _width * _height * 4;

// Access pixel data
unsigned char* pSrc = static_cast<unsigned char*>( mapped.pData );

// Offsets
int offsetSrc = 0;
int offsetDst = 0;
int rowOffset = mapped.RowPitch % _width;

// Loop through it, BRGA to RGBA conversation
for (int row = 0; row < _height; ++row)
{
    for (int col = 0; col < _width; ++col)
    {
        pDest[offsetDst] = pSrc[offsetSrc+2];
        pDest[offsetDst+1] = pSrc[offsetSrc+1];
        pDest[offsetDst+2] = pSrc[offsetSrc];
        pDest[offsetDst+3] = pSrc[offsetSrc+3];

        offsetSrc += 4;
        offsetDst += 4;
    }

    // Adjuste offset
    offsetSrc += rowOffset;
}

// Unmap texture
pContext->Unmap( texStaging, 0 );

解决方案:

    Texture2D txDiffuse : register(t0);
SamplerState texSampler : register(s0);

struct VSScreenQuadOutput
{
float4 Position : SV_POSITION;
float2 TexCoords0 : TEXCOORD0;
};

float4 PSMain(VSScreenQuadOutput input) : SV_Target
{
return txDiffuse.Sample(texSampler, input.TexCoords0).rgba;
}

【问题讨论】:

  • 您使用的“显示库”是什么?任何半体面的 DX11 渲染库都应该能够正确处理 BGRA 和 RGBA 格式(以及 BC1、BC7 等)。
  • 这是一个 3D 引擎,为什么不支持某些格式。因此,我试图找到一种解决方法。

标签: directx-11


【解决方案1】:

显然,在 CPU 上迭代纹理并不是最有效的方法。如果您知道纹理中的颜色总是这样交换,并且您不想在 C++ 代码中修改纹理本身,那么最直接的方法是在像素着色器中进行。当您对纹理进行采样时,只需在此处交换颜色即可。您甚至不会注意到任何性能下降。

【讨论】:

  • 您好!非常感谢您的帮助!你有示例代码吗?我通过了我的 DX11 圣经,但什么也没找到。我也找不到与在其他地方使用像素着色器交换颜色相关的任何内容。
  • 好的,我假设您使用的是 HLSL。在您的像素着色器代码中,您应该有一个读取纹理的位置。我相信它或多或少会像这样:“float4 finalColor=myTexture.Sample(colorSampler, uv);”所以你需要在 finalColor 向量中交换颜色。就像这样:finalColor = float4(finalColor.g,finalColor.b,finalColor.r,finalColor.a);
  • 您好!我仍在阅读有关应用像素着色器的教程。一旦我能够正确理解该主题,我将在此处发布结果。 (野外教程不多)
  • 我明白了!非常感谢。
猜你喜欢
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多