我想用 BGRA 格式从指向像素缓冲区的指针创建一个纹理,它会不断更改/更新其值。 我想在每一帧的左上角将这个纹理绘制到屏幕上。
利用我的一些 XNA 和 OpenGL 知识,我弄清楚了其中的一些,但我无法获取纹理以查看缓冲区的变化。我也不知道如何正确绘制纹理,所以我创建了一个 Sprite (就像在 XNA 中一样)。
我写了以下内容..
DirectX 9:
void CreateSprite(IDirect3DDevice9* Device, ID3DXSprite* &Sprite)
{
D3DXCreateSprite(Device, Sprite);
}
void DrawSprite(IDirect3DTexture9* Texture, ID3DXSprite* Sprite, D3DXVECTOR3 Position)
{
Sprite->Begin(D3DXSPRITE_ALPHABLEND);
sprite->Draw(Texture, nullptr, nullptr, &Position, 0xFFFFFFFF);
Sprite->End();
//SafeRelease(Sprite);
//SafeRelease(Texture);
}
void BufferToTexture(IDirect3DDevice9* Device, BufferInfo* BuffPtr)
{
if (BuffPtr != nullptr)
{
if (Texture == nullptr)
{
Device->CreateTexture(BuffPtr->width, BuffPtr->height, 1, 0, D3DFMT_X8B8G8R8, D3DPOOL_MANAGED, &Texture, 0);
}
else
{
D3DLOCKED_RECT rect;
Texture->LockRect(&rect, 0, D3DLOCK_DISCARD);
std::uint8_t* dest = static_cast<std::uint8_t*>(rect.pBits);
memcpy(dest, BuffPtr->Pixels, BuffPtr->width * BuffPtr->height * 4);
Texture->UnlockRect(0);
}
//I modify the Pixel Buffer. Not sure if the Texture will see these changes.
//Would be better if I can make the texture's rect.pBits point to BuffPtr->Pixels.
//So that I can avoid the above memcpy.
std::uint8_t* Ptr = (std::uint8_t*)BuffPtr->Pixels;
for (int I = 0; I < BuffPtr->height; ++I)
{
for (int J = 0; J < BuffPtr->width; ++J)
{
std::uint8_t B = *(Ptr++);
std::uint8_t G = *(Ptr++);
std::uint8_t R = *(Ptr++);
*(Ptr++) = (B == 0 && G == 0 && R == 0) ? 0 : 0xFF;
}
}
}
}
在 OpenGL 中,代码直接使用像素缓冲区。对缓冲区的任何更改也会发生在纹理上,并且不会进行任何复制。该代码允许我直接在屏幕上绘制一个像素数组。我试图在 DirectX 中完成同样的事情,但我不确定如何让纹理看到缓冲区中的变化。另外,我不确定如何将我的 DirectX 纹理绘制到屏幕上。
最佳答案
"Not sure if the Texture will see these changes."
不,不会,因为您在Unlock
rect 后对内存进行了更改。在 D3D 中锁定和解锁资源类似于在 OpenGL 中取消映射缓冲区对象。
至于为什么它在 OpenGL 中工作,我只能想象您在 外部 函数 BufferToTexture (...)
。如果您更改 D3D 代码以使其也以这种方式工作,那么您应该会努力解决这个问题。
您还应该知道 D3D 使用不同的纹理原点:(0,0) 在 D3D 中是左上角,在 OpenGL 中是左下角。
关于c++ - OpenGL 到 DirectX(缓冲区到纹理到屏幕),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20724043/