HRESULT HookIDirect3DDevice9::GetRenderTargetData(LPVOID _this, IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) { LOG_API(); return pD3Dev->GetRenderTargetData(pRenderTarget, pDestSurface); }
void* CDX9TextureObject::Read( int level, bool bForceUpdateRead ) { ReadyData(); //level currently ignored, read cannot read mipmaps if( m_Texture ) { LPDIRECT3DDEVICE9 pDevice; if( !m_Renderer ) { return NULL; } pDevice = (LPDIRECT3DDEVICE9)m_Renderer->GetAPIDevice(); if( !pDevice ) { return NULL; } int iTextureSize = (GetColorDepth() / 8) * GetWidth() * GetHeight(); // delete the old buffer if our current one is the wrong size if (m_pLocalBuffer && (iTextureSize != m_iLocalBufferSize)) { delete[] m_pLocalBuffer; m_pLocalBuffer = NULL; m_iLocalBufferSize = 0; } // allocate a new buffer if we don't have one if (!m_pLocalBuffer) { m_pLocalBuffer = new unsigned char[iTextureSize]; m_iLocalBufferSize = iTextureSize; } else { // return current buffer if we aren't forcing a read if (!bForceUpdateRead) return m_pLocalBuffer; } //check what kind of a surface it is, we have to get the surface if it's a rendertarget! if( !m_bRenderTarget ) { if( m_Compressed ) { LPDIRECT3DSURFACE9 Src = NULL; m_Texture->GetSurfaceLevel( 0, &Src ); //convert format to argb first LPDIRECT3DSURFACE9 tempSurf = NULL; HRESULT hr = pDevice->CreateOffscreenPlainSurface( GetWidth(), GetHeight(), D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tempSurf, NULL ); if( hr != D3D_OK || tempSurf == NULL || Src == NULL ) { SAFE_RELEASE( Src ); SAFE_RELEASE( tempSurf ); return NULL; } hr = D3DXLoadSurfaceFromSurface( tempSurf, NULL, NULL, Src, NULL, NULL, D3DX_DEFAULT, 0 ); if( hr != D3D_OK ) { return NULL; } //lock the texture and read the data D3DLOCKED_RECT lockrect; hr = tempSurf->LockRect( &lockrect, NULL, D3DLOCK_READONLY ); if( hr == D3D_OK ) { UINT pixelsize = (GetColorDepth()/8); BYTE * srcbits = (BYTE*)lockrect.pBits; BYTE * destbits = (BYTE*)m_pLocalBuffer; //write the texture to the buffer for( UINT i = 0; i < m_Height; i++ ) { memcpy( destbits, srcbits, m_Width*pixelsize ); //move by pitch srcbits += lockrect.Pitch; destbits += m_Width*pixelsize; } } tempSurf->UnlockRect(); SAFE_RELEASE( tempSurf ); SAFE_RELEASE( Src ); return m_pLocalBuffer; } else { //lock the texture and read the data D3DLOCKED_RECT lockrect; HRESULT hr = m_Texture->LockRect( 0, &lockrect, NULL, D3DLOCK_READONLY ); if( hr == D3D_OK ) { UINT pixelsize = (GetColorDepth()/8); BYTE * srcbits = (BYTE*)lockrect.pBits; BYTE * destbits = (BYTE*)m_pLocalBuffer; //write the texture to the buffer for( UINT i = 0; i < m_Height; i++ ) { memcpy( destbits, srcbits, m_Width*pixelsize ); //move by pitch srcbits += lockrect.Pitch; destbits += m_Width*pixelsize; } } m_Texture->UnlockRect( 0 ); return m_pLocalBuffer; } }else//we are render target, need surface { LPDIRECT3DSURFACE9 RenderSurf = NULL; LPDIRECT3DSURFACE9 OffSurf = NULL; m_Texture->GetSurfaceLevel( 0, &RenderSurf ); if( RenderSurf ) { D3DSURFACE_DESC tDesc; m_Texture->GetLevelDesc(0, &tDesc ); if( FAILED(pDevice->CreateOffscreenPlainSurface( tDesc.Width, tDesc.Height, tDesc.Format, D3DPOOL_SYSTEMMEM, &OffSurf, NULL ))) { RenderSurf->Release(); return NULL; } if( FAILED( pDevice->GetRenderTargetData( RenderSurf, OffSurf ) )) { RenderSurf->Release(); OffSurf->Release(); return NULL; } //No need for rendertarget surface anymore RenderSurf->Release(); //lock the texture and read the data D3DLOCKED_RECT lockrect; HRESULT hr = OffSurf->LockRect( &lockrect, NULL, D3DLOCK_READONLY ); if( hr == D3D_OK ) { UINT pixelsize = (GetColorDepth()/8); BYTE * srcbits = (BYTE*)lockrect.pBits; BYTE * destbits = (BYTE*)m_pLocalBuffer; //write the texture to the buffer for( UINT i = 0; i < m_Height; i++ ) { memcpy( destbits, srcbits, m_Width*pixelsize ); //move by pitch srcbits += lockrect.Pitch; destbits += m_Width*pixelsize; } } OffSurf->UnlockRect(); OffSurf->Release(); } return m_pLocalBuffer; } } return NULL; }
void Texture::SaveToSystemMemory() { if (isRenderTarget) { /* Do not save texture if autosave flag is false */ if (!renderTargetAutosave) return; HRESULT hr = RenderManager::Instance()->GetD3DDevice()->TestCooperativeLevel(); if (hr == D3DERR_DEVICELOST) { //if (!saveTexture) //Logger::FrameworkDebug("Trying to save to system memory rendertarget that was not saved before"); return; } // Render manager set this flag when you set sprite as render target. if (!renderTargetModified) return; // Release should be after check that renderTargetModified. D3DSafeRelease(saveTexture); LPDIRECT3DDEVICE9 device = RenderManager::Instance()->GetD3DDevice(); D3DSURFACE_DESC desc; id->GetLevelDesc(0, &desc); //Logger::FrameworkDebug("Saving render target to system memory: %s size: %d x %d format:%d", relativePathname.c_str(), width, height, desc.Format); /* HRESULT hr = device->CreateOffscreenPlainSurface(width, height, desc.Format, D3DPOOL_SYSTEMMEM, &saveSurface, NULL); DX_VERIFY(hr); */ hr = device->CreateTexture(width, height, 1/*means we create texture with 1 mipmap level*/, 0, desc.Format, D3DPOOL_SYSTEMMEM, &saveTexture, 0); RENDER_VERIFY(hr); LPDIRECT3DSURFACE9 renderTargetMainSurface; hr = id->GetSurfaceLevel(0, &renderTargetMainSurface); RENDER_VERIFY(hr); LPDIRECT3DSURFACE9 saveTextureMainSurface; hr = saveTexture->GetSurfaceLevel(0, &saveTextureMainSurface); RENDER_VERIFY(hr); hr = device->GetRenderTargetData(renderTargetMainSurface, saveTextureMainSurface); RENDER_VERIFY(hr); renderTargetModified = false; #if 0 //Image * image = new Image(); Image * image = image->Create(width, height, FORMAT_RGBA8888); D3DLOCKED_RECT rect; hr = saveTexture->LockRect(0, &rect, 0, 0); if (FAILED(hr)) { Logger::Error("[TextureDX9] Could not lock DirectX9 Texture."); return; } int32 pixelSizeInBits = GetPixelFormatSize(format); if (format == FORMAT_RGBA8888) { //int32 pitchInBytes = uint8 * destBits = (uint8*)image->GetData(); uint8 * sourceBits = (uint8*)rect.pBits; for (uint32 h = 0; h < height * width; ++h) { uint32 b = sourceBits[0]; uint32 g = sourceBits[1]; uint32 r = sourceBits[2]; uint32 a = sourceBits[3]; destBits[0] = (uint8)r; //sourceBits[3]; destBits[1] = (uint8)g; //sourceBits[0]; destBits[2] = (uint8)b;//sourceBits[1]; destBits[3] = (uint8)a; destBits += 4; sourceBits += 4; } } saveTexture->UnlockRect(0); image->Save(Format("FBO\\%s.png", relativePathname.c_str())); SafeRelease(image); #endif D3DSafeRelease(renderTargetMainSurface); D3DSafeRelease(saveTextureMainSurface); } }