3

DirectX プログラムのすべてのフレームを YUV (ビデオ エンコーディング用) に変換しようとしています。したがって、最初にすべてのフレームの各ピクセルの RGB(A) 値が必要です。バックバッファからこれらを取得する必要があります。

DirectX には glReadPixels がないため、次のようにします。

  1. バックバッファの renderTargetView へのポインタを取得し、バックバッファ リソースを取得します
  2. このリソースをキャストするID3D10Texture2D
  3. ステージング テクスチャとCopyResource、前の手順の texture2D を作成します。

この時点で使用できD3DX10SaveTextureToFile、このステージング テクスチャはバックバッファを画像として正しく保存します。

ただし、ディスクを迂回するのではなく、すぐに RGB データを取得したいので、次のようにします。

  1. ステージング リソースをマップする
  2. マッピングされたテクスチャの pData を読み取り、RGB(A) 値を取得します

問題: RGB 値がゴミです。これはピクセル (1,1) の例です

(1、1)=(-17014118346046923000000000000000000000000000000、-170141183460469230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

同じコードを使用して別のステージング テクスチャ (別のオフスクリーン レンダー ターゲットから) をマップすると、このコードはそこで問題なく動作するため、これは特に奇妙です。

これは私のコードです:

// Get resource pointer to backbuffer
ID3D10Resource *backbufferRes;
m_D3D->GetRenderTargetView()->GetResource(&backbufferRes);

// Cast backbuffer resource to texture2D
ID3D10Texture2D* tempTexture = 0;
backbufferRes->QueryInterface(__uuidof(ID3D10Texture2D),(LPVOID*) &tempTexture);
backbufferRes->Release();

// Get the descriptor of this texture2D
D3D10_TEXTURE2D_DESC descDefault; 
tempTexture->GetDesc(&descDefault);

// Create a staging texture desc based on the texture of the backbuffer
D3D10_TEXTURE2D_DESC descStaging;
descStaging = descDefault;
descStaging.Usage = D3D10_USAGE_STAGING;
descStaging.CPUAccessFlags = D3D10_CPU_ACCESS_READ;  
descStaging.BindFlags = 0;

// Create the new empty staging texture
ID3D10Texture2D *texture = 0;
m_D3D->GetDevice()->CreateTexture2D( &descStaging, NULL, &texture);

// Copy the backbuffer texture data (tempTexture) to the staging texture (texture)
m_D3D->GetDevice()->CopyResource(texture, tempTexture);

// This call works perfectly, image is correct!
// D3DX10SaveTextureToFile(texture, D3DX10_IFF_BMP, L"D:\\img.bmp");

// We want to avoid disk access, so instead let's map the texture and read its RGB data
D3D10_MAPPED_TEXTURE2D mappedTexture;
hr = texture->Map(D3D10CalcSubresource(0, 0, 1), D3D10_MAP_READ, 0, &mappedTexture);
FLOAT* m_pBits = (FLOAT*) malloc(4 * descStaging.Width * descStaging.Height * sizeof(FLOAT));
if(!FAILED(hr)) {
    memcpy(m_pBits, mappedTexture.pData, 4 * descStaging.Width * descStaging.Height);
    texture->Unmap(D3D10CalcSubresource(0, 0, 1));
}
texture->Release();
tempTexture->Release();

fp = fopen("D:\\output.txt", "a");
for( UINT row = 0; row < descStaging.Height; row++ )
{
    UINT rowStart = row * mappedTexture.RowPitch / 4;
    for( UINT col = 0; col < descStaging.Width; col++ )
    {
        r = m_pBits[rowStart + col*4 + 0]; // Red (X)
        g = m_pBits[rowStart + col*4 + 1]; // Green (Y)
        b = m_pBits[rowStart + col*4 + 2]; // Blue (Z)
        a = m_pBits[rowStart + col*4 + 3]; // Alpha (W)

        // Save pixel values to disk
        fprintf(fp, "%d %d - %f %f %f\n",  col + 1, row + 1, r, g, b);
    }
}
fclose(fp);

問題が何であるかについて誰かが考えを持っていますか? すべてのヘルプは本当に感謝しています。

4

1 に答える 1