2011-06-22 3 views
1

私はDX9レンダラーを作成しています。現在、AVIムービーファイルを再生する機能に取り組んでいます。私はパックされたDIBを返すAVIStreamGetFrame()を使用して指定されたフレームを取得できました。そこから既にビットマップデータを既存のIDirect3DTexture9 *にコピーできるようにしたいと思います。IDirect3DTexture9にBITMAPINFOHEADERイメージデータを書き込む

ビットマップファイル形式の理解が不十分で、BITMAPINFOHEADERから与えられたピクセルデータをIDirect3DTexture9が解釈できる形式に変換する方法を知っていません。

私が最初にこのように私のDX9テクスチャを作成します。私はここにある

LPBITMAPINFO bmpInfo = m_pVideoData->GetVideoFormat(); 
D3DXCreateTexture(LtGEngine::GetInstance()->GetDevice(), 
        bmpInfo->bmiHeader.biWidth, 
        bmpInfo->bmiHeader.biHeight, 
        D3DX_DEFAULT, 
        0, 
        D3DFMT_A8R8G8B8, // <- DETERMINE HOW? 
        D3DPOOL_MANAGED, // <- OR D3DPOOL_SYSTEMMEM? 
        &m_pD3DTexture); 

質問は、上記のコメントとして記載されています。私はBITMAPINFOを取得し、例えばbmpInfo.bmiHeader.biBitCount = 8(または16など)を読み込むと、これはD3DFMT_ *をそれに応じて変更する必要があるということですか?

後でレンダリングするフレームにLPBITMAPINFOHEADERが表示されたら、IDirect3DTexture9::LockRect()関数から返されたpBitsの処理方法が失われます。これまで私がこれまで持っていたことは次のとおりです。

// Retrieve a frame from the video data as a BITMAPINFOHEADER 
LPBITMAPINFOHEADER pBmpInfoHeader; 
m_pVideoData->GetVideoFrame(0, 0, &pBmpInfoHeader); 

D3DLOCKED_RECT rect; 
if(FAILED(m_pD3DTexture->LockRect(0, &rect, NULL, 0))) 
{ 
    m_pD3DTexture->UnlockRect(0); 
} 
DWORD* pDest = (DWORD*)rect.pBits; 
// Now what to copy from pBmpInfoHeader? 

これは私には見られないAPIコールがありますか?それとも誰よりも簡単な方法を知っていますか?読んでいただきありがとうございます。

答えて

1

これは機能しました。

カップルノートを考慮する。私のAVIファイル(この場合は単一のフレーム/ビットマップ)は16ビット形式であったため、D3DFMT_X1R5G5B5でデスティネーションテクスチャを作成しなければなりませんでした。また、ビットマップは逆さまに格納されているので、ポインタを逆にして各行を逆方向に読み取らなければなりませんでした。

// Retrieve a frame from the video data as a BITMAPINFOHEADER 
LPBITMAPINFOHEADER pBmpInfoHeader; 
m_pVideoData->GetVideoFrame(0, 0, &pBmpInfoHeader); 

// Get dimentions 
long nWidth = pBmpInfoHeader->biWidth; 
long nHeight = pBmpInfoHeader->biHeight; 

// Bitmap width correction (might not be needed...) 
if (nWidth % 4 != 0) 
    nWidth = nWidth + (4 - nWidth%4); 

// Get Pixel data (should be after the header in memory) 
WORD bitCount = pBmpInfoHeader->biBitCount; 
DWORD size = nWidth * nHeight * bitCount/8; 
BYTE *pPixelSrc = (BYTE *)pBmpInfoHeader + sizeof(pBmpInfoHeader); 

// Lock the texture so we can write this frame's texel data 
D3DLOCKED_RECT lock; 
if(FAILED(m_pD3DTexture->LockRect(0, &lock, NULL, 0))) 
{ 
    m_pD3DTexture->UnlockRect(0); 
    return; 
} 

int iNumBytesPerRowSrc = pBmpInfoHeader->biWidth * (pBmpInfoHeader->biBitCount/8); 
int iNumBytesPerRowDst = lock.Pitch; 
int iNumBytesToCopyPerRow = min(iNumBytesPerRowSrc, iNumBytesPerRowDst); 

// Bitmap data is stored upside down 
// Start at the end and work backwards 
pPixelSrc += (iNumBytesPerRowSrc * nHeight); 

// Store a pointer to the texture pixel data and write new data 
BYTE* ucTexDst = (BYTE *)lock.pBits; 
for(int y = 0; y < nHeight; ++y) 
{ 
    pPixelSrc -= iNumBytesPerRowSrc; 
    memcpy(ucTexDst, pPixelSrc, iNumBytesToCopyPerRow); 
    ucTexDst += iNumBytesPerRowDst; 
} 

// Unlock texture so gfx card can resume its business 
m_pD3DTexture->UnlockRect(0); 
+1

ありがとう:

は、ここでは、コードです。この解決策は、古いコードを修正するのに役立ちました。 –