예제 #1
0
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;
}
예제 #3
0
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);
    }
}