C++ 将BitMapInfo标头图像数据写入IDirect3DTexture9

C++ 将BitMapInfo标头图像数据写入IDirect3DTexture9,c++,bitmap,textures,directx-9,C++,Bitmap,Textures,Directx 9,我正在编写一个DX9渲染器,目前正在研究播放AVI电影文件的能力。我已经能够使用avirstreamgetframe()检索任何指定的帧,它返回一个压缩的DIB,并且从那里我希望能够将位图数据复制到一个已经存在的IDirect3DTexture9* 我的问题是不了解位图文件格式,不知道如何将从BitMapInfo头提供的像素数据转换为IDirect3DTexture9可以解释的格式 我首先创建DX9纹理,如下所示: LPBITMAPINFO bmpInfo = m_pVideoData->

我正在编写一个DX9渲染器,目前正在研究播放AVI电影文件的能力。我已经能够使用
avirstreamgetframe()
检索任何指定的帧,它返回一个压缩的DIB,并且从那里我希望能够将位图数据复制到一个已经存在的
IDirect3DTexture9*

我的问题是不了解位图文件格式,不知道如何将从
BitMapInfo头
提供的像素数据转换为
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);
有没有我没有见过的API调用可以为我实现这一点?或者有人知道比这更简单的方法吗?谢谢你的阅读/帮助

成功了

夫妻双方要考虑。我的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);
//从视频数据中检索一帧作为BitMapInfo标头
LPBitMapInfo头PBMPInfo头;
m_pVideoData->GetVideoFrame(0、0和pbmpinfo头);
//获取维度
长nWidth=pbmpinfo头->双宽度;
长N高度=PBMPInfo收割台->双高度;
//位图宽度校正(可能不需要…)
如果(nWidth%4!=0)
nWidth=nWidth+(4-nWidth%4);
//获取像素数据(应位于内存中的标题之后)
字位计数=PBMPInfo头->位计数;
DWORD大小=nWidth*nHeight*比特数/8;
字节*pPixelSrc=(字节*)pBmpInfoHeader+sizeof(pBmpInfoHeader);
//锁定纹理,以便我们可以写入此帧的texel数据
D3D锁紧的直锁;
if(失败(m_pD3DTexture->LockRect(0,&lock,NULL,0)))
{
m_pD3DTexture->UnlockRect(0);
返回;
}
int iNumBytesPerRowSrc=pbmpinfo头->biWidth*(pbmpinfo头->bibibitcount/8);
int iNumBytesPerRowDst=锁定节距;
int iNumBytesToCopyPerRow=min(iNumBytesPerRowSrc,iNumBytesPerRowDst);
//位图数据是颠倒存储的
//从末尾开始,然后倒转
pPixelSrc+=(单位为字节的错误代码*n右);
//存储指向纹理像素数据的指针并写入新数据
字节*ucTexDst=(字节*)lock.pBits;
对于(整数y=0;yUnlockRect(0);
成功了

夫妻双方要考虑。我的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);
//从视频数据中检索一帧作为BitMapInfo标头
LPBitMapInfo头PBMPInfo头;
m_pVideoData->GetVideoFrame(0、0和pbmpinfo头);
//获取维度
长nWidth=pbmpinfo头->双宽度;
长N高度=PBMPInfo收割台->双高度;
//位图宽度校正(可能不需要…)
如果(nWidth%4!=0)
nWidth=nWidth+(4-nWidth%4);
//获取像素数据(应位于内存中的标题之后)
字位计数=PBMPInfo头->位计数;
DWORD大小=nWidth*nHeight*比特数/8;
字节*pPixelSrc=(字节*)pBmpInfoHeader+sizeof(pBmpInfoHeader);
//锁定纹理,以便我们可以写入此帧的texel数据
D3D锁紧的直锁;
if(失败(m_pD3DTexture->LockRect(0,&lock,NULL,0)))
{
m_pD3DTexture->UnlockRect(0);
返回;
}
int iNumBytesPerRowSrc=pbmpinfo头->biWidth*(pbmpinfo头->bibibitcount/8);
int iNumBytesPerRowDst=锁定节距;
int iNumBytesToCopyPerRow=min(iNumBytesPerRowSrc,iNumBytesPerRowDst);
//位图数据是颠倒存储的
//从末尾开始,然后倒转
pPixelSrc+=(单位为字节的错误代码*n右);
//存储指向纹理像素数据的指针并写入新数据
字节*ucTexDst=(字节*)lock.pBits;
对于(整数y=0;yUnlockRect(0);

谢谢。此解决方案帮助我修补了一些旧代码。谢谢。这个解决方案帮助我修补了一些旧代码。