Копирование данных рендеринга цели в D3DPOOL_MANAGED?

я используя двигатель который использует DirectX9.

Он создает цели рендеринга, используя:

D3DXCreateTexture(
pD3DDevice, width, height, 1,
D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT, &pRT
)

И все остальные текстуры создаются так:

D3DXCreateTexture(
pD3DDevice, width, height,
1, 0, D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED, &pTex
)

Стоит отметить, что бэкбуфер тоже D3DFMT_X8R8G8B8 поэтому я не уверен, почему текстуры создаются по-другому … но я полагаю, «если он не сломан, не чините его» право? Все текстуры загружаются / отображаются просто отлично.
Для получения более подробной информации о том, как работает этот двигатель, вот код основного графического модуля.
(в основном обратите внимание на Target_Create а также Texture_Create методы) …

ТЕМ НЕ МЕНИЕ, У меня было множество проблем, пытаясь придерживаться этих правил, пытаясь преобразовать целевую текстуру рендеринга в обычную текстуру. Движок не имеет встроенной функциональности для этого, и цели рендеринга рассматриваются как отдельные объекты от текстур … И, в свою очередь, это ограничивает мою способность на самом деле ИСПОЛЬЗОВАНИЕ все, что требует цели рендеринга (например, пиксельные шейдеры и т. д.). Конечный результат заключается в том, что мне нужно найти способ скопировать эти целевые данные рендеринга в текстуру, созданную, как описано выше, которую движок мог бы использовать без какого-либо конфликта.

Я пробовал что-то вроде следующего:

inline PVOID LockedBits(LPDIRECT3DSURFACE9 surface, UINT w, UINT h, INT* size)
{
D3DLOCKED_RECT lr;
RECT rc = {0, 0, w, h};
surface->LockRect(&lr, &rc, 0);
if(size) *size = (w*h) * 4;
return lr.pBits;
}
inline PVOID LockedBits(LPDIRECT3DTEXTURE9 texture, UINT w, UINT h, INT* size)
{
D3DLOCKED_RECT lr;
RECT rc = {0, 0, w, h};
texture->LockRect(0, &lr, &rc, 0);
if(size) *size = (w*h) * 4;
return lr.pBits;
}

LPDIRECT3DTEXTURE9 CloneTextureFromTarget(LPDIRECT3DDEVICE9 device, LPDIRECT3DTEXTURE9 target, UINT w, UINT h)
{
D3DDISPLAYMODE dm;
device->GetDisplayMode(0, &dm);

// Create source and destination surfaces and copy rendertarget
LPDIRECT3DSURFACE9 dstSurf = NULL, srcSurf = NULL;
device->CreateOffscreenPlainSurface(w, h, dm.Format, D3DPOOL_SYSTEMMEM, &dstSurf, NULL);
target->GetSurfaceLevel(0, &srcSurf);
device->GetRenderTargetData(srcSurf, dstSurf);
SafeRelease(&srcSurf);

// Create destination texture
LPDIRECT3DTEXTURE9 dstTexture = NULL;
D3DXCreateTexture(device, w, h, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &dstTexture);

// Get bits for destination surface and texture
INT dwSrc, dwDst;
PVOID pBitsSrc = LockedBits(dstSurf, w, h, &dwSrc);
PVOID pBitsDst = LockedBits(dstTexture, w, h, &dwDst);

// Copy bits from surface to texture
RtlCopyMemory(pBitsSrc, pBitsDst, dwSrc);
dstTexture->UnlockRect(0);
dstSurf->UnlockRect();
SafeRelease(&dstSurf);

/* Just to double-check if it worked... */
D3DXSaveTextureToFileA("C:\\outSrc.png", D3DXIFF_PNG, target, NULL);
D3DXSaveTextureToFileA("C:\\outDst.png", D3DXIFF_PNG, dstTexture, NULL);

// Return the result
return dstTexture;
}

Результатом этого кода является то, что обе текстуры должным образом сохраняются на диск и выходят, как и ожидалось, но отказываются правильно отображать …

Я делаю что-то неправильно?
Каков наилучший способ добиться идеального копирования этих данных в новую текстуру, созданную с помощью D3DFMT_A8R8G8B8 а также D3DPOOL_MANAGED?

1

Решение

TBH измените ваш метод копирования следующим образом:

char* pSrc = (char*)pBitsSrc;
char* pDst = (char*)pBitsDst;
int p = 0;
int pMax = w * h;
while( p < pMax )
{
// Copy B
*pDst = *pSrc;
pDst++;
pSrc++;
// Copy G
*pDst = *pSrc;
pDst++;
pSrc++;
// Copy R
*pDst = *pSrc;
pDst++;
pSrc++;
// Set A
*pDst = 0xff;
pDst++;
pSrc++;
p++;
}

Или, если это невозможно, просто создайте целевую текстуру как D3DFMT_X8R8G8B8.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]