2013-05-01 1 views
1

저는 DirectX9를 사용하는 using an engine입니다.렌더 대상 데이터를 D3DPOOL_MANAGED에 복사 중입니까?

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 그래서 텍스처가 다르게 생성되는 이유는 확실하지 않지만 ... "파산하지 않았 으면 고치지 마라." 맞습니까? 모든 텍스처는 잘로드/렌더링하는 것처럼 보입니다. 이 엔진의 작동 방식에 대한 자세한 내용은 here is it's main graphics module's code입니다.
는 (주로 Target_CreateTexture_Create 방법에주의) ...

그러나이, 나는에 렌더 타겟 텍스처를 변환하는 동안 이러한 규칙을 고수하려고 문제의 톤을 했어 일반 질감. 엔진은 이것을위한 내장 된 기능을 가지고 있지 않으며, 렌더 타겟은 텍스처로부터 분리 된 객체로 취급됩니다 ... 그리고 실제로, 이것은 내 능력을 실제적으로 제한합니다. USE 렌더 타겟을 필요로하는 것은 무엇 이든요 (예 : 픽셀 쉐이더 등)). 최종 결과는 엔진이 충돌없이 사용할 수 있도록 위의 방법으로 생성 된 텍스처에이 렌더링 타겟 데이터를 복사하는 방법을 찾아야한다는 것입니다. 나는 다음과 같은 것을 시도

:

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_A8R8G8B8D3DPOOL_MANAGED으로 만든 새 텍스처로이 데이터를 완벽하게 복사하는 가장 좋은 방법은 무엇입니까? 다음과 같이

+1

렌더 타겟을'D3DFMT_A8R8G8B8'로 생성 할 수 있습니다. 장치의 후방 버퍼 만'D3DFMT_X8R8G8B8'으로 생성해야합니다. 또한이 렌더링 타겟은 일반적으로 렌더링에 사용할 수 있지만 잠금 작업에는 사용할 수 없습니다. 자물쇠가 필요하거나 렌더 타겟을 백 버퍼에 렌더링하고 싶습니까? – Gnietschow

+0

만약'D3DFMT_A8R8G8B8'을 사용하여 그것을 생성한다면, 나는 더 이상 rendertarget 객체를 사용하지 않을 것이고 사용하는 모든 자원을 비우고 싶기 때문에 새로운'D3DPOOL_MANAGED' 텍스처로 그것을 제거하는 방법을 여전히 요구할 것입니다 . 엔진은 텍스쳐와 렌더 타겟을 별도의 객체로 취급합니다. 렌더 타겟은 더 많은 리소스를 저장/소비합니다 ... 그리고 렌더링을 위해서, 어플리케이션은 텍스처 객체의 배열을 사용합니다. 그래서 렌더링 타겟은 초기화 중에 새로운 텍스처를 생성하기 위해서만 사용됩니다 (픽셀 쉐이더)이 배열의'D3DPOOL_MANAGED' 텍스처에 추가합니다. – RectangleEquals

+0

그래서 렌더링 타겟을 잠그면 ...새로 생성 된'D3DPOOL_MANAGED' 텍스처로 데이터를 복제 할 수 있다면 (아무튼), 잠금 지원이 필요하지 않습니다. 그렇지 않으면 그렇습니다. 어떻게이 데이터를 새로운 텍스처로 안전하게 복제 할 수 있었는지 생각해보십시오. 또한 위 코드가 효과가 있습니까? 나를 위해, 그것은 디스크에 이미지를 올바르게 저장하는 것처럼 보이지만 어떻게 든 내 응용 프로그램에서 렌더링하지 못합니다. – RectangleEquals

답변

0

은 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로 대상 텍스처를 만들 실패.

관련 문제