DX11将像素格式BGRA转换为RGBA [英] DX11 convert pixel format BGRA to RGBA

查看:497
本文介绍了DX11将像素格式BGRA转换为RGBA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have currently the problem that a library creates a DX11 texture with BGRA pixel format. But the displaying library can only display RGBA correctly. (This means the colors are swapped in the rendered image)

环顾四周后,我发现了一个简单的for循环来解决问题,但性能不是很好,并且分辨率较差时会缩放。我是DirectX的新手,也许我只是错过了一个简单的函数来进行转换。

After looking around I found a simple for-loop to solve the problem, but the performance is not very good and scales bad with higher resolutions. I'm new to DirectX and maybe I just missed a simple function to do the converting.

// 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;
}


推荐答案

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

Obviously iterating over a texture on you CPU is not the most effective way. If you know that colors in a texture are always swapped like that and you don't want to modify the texture itself in your C++ code, the most straightforward way would be to do it in the pixel shader. When you sample the texture, simply swap colors there. You won't even notice any performance drop.

这篇关于DX11将像素格式BGRA转换为RGBA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆