RageSurface* RageDisplay_D3D::CreateScreenshot() { #if defined(XBOX) return NULL; #else /* Get the back buffer. */ IDirect3DSurface8* pSurface; g_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pSurface ); /* Get the back buffer description. */ D3DSURFACE_DESC desc; pSurface->GetDesc( &desc ); /* Copy the back buffer into a surface of a type we support. */ IDirect3DSurface8* pCopy; g_pd3dDevice->CreateImageSurface( desc.Width, desc.Height, D3DFMT_A8R8G8B8, &pCopy ); D3DXLoadSurfaceFromSurface( pCopy, NULL, NULL, pSurface, NULL, NULL, D3DX_DEFAULT, 0 ); pSurface->Release(); /* Update desc from the copy. */ pCopy->GetDesc( &desc ); D3DLOCKED_RECT lr; { RECT rect; rect.left = 0; rect.top = 0; rect.right = desc.Width; rect.bottom = desc.Height; pCopy->LockRect( &lr, &rect, D3DLOCK_READONLY ); } RageSurface *surface = CreateSurfaceFromPixfmt( FMT_RGBA8, lr.pBits, desc.Width, desc.Height, lr.Pitch); ASSERT( surface ); /* We need to make a copy, since lr.pBits will go away when we call UnlockRect(). */ RageSurface *SurfaceCopy = CreateSurface( surface->w, surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask ); RageSurfaceUtils::CopySurface( surface, SurfaceCopy ); delete surface; pCopy->UnlockRect(); pCopy->Release(); return SurfaceCopy; #endif }
RageSurface* RageDisplay_D3D::CreateScreenshot() { // Get the back buffer. IDirect3DSurface8* pSurface; g_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pSurface ); // Get the back buffer description. D3DSURFACE_DESC desc; pSurface->GetDesc( &desc ); // Copy the back buffer into a surface of a type we support. IDirect3DSurface8* pCopy; g_pd3dDevice->CreateImageSurface( desc.Width, desc.Height, D3DFMT_A8R8G8B8, &pCopy ); // Aldo_MX: D3DXLoadSurfaceFromSurface requires d3dx8core.h, I replaced it with CopyRects to // remove this dependency so its possible to compile SM with any DirectX SDK up to Aug 2007 D3DXLoadSurfaceFromSurface( pCopy, NULL, NULL, pSurface, NULL, NULL, D3DX_DEFAULT, 0 ); //g_pd3dDevice->CopyRects( pSurface, NULL, 0, pCopy, NULL ); pSurface->Release(); // Update desc from the copy. pCopy->GetDesc( &desc ); D3DLOCKED_RECT lr; { RECT rect; rect.left = 0; rect.top = 0; rect.right = desc.Width; rect.bottom = desc.Height; pCopy->LockRect( &lr, &rect, D3DLOCK_READONLY ); } RageSurface *surface = CreateSurfaceFromPixfmt( PixelFormat_RGBA8, lr.pBits, desc.Width, desc.Height, lr.Pitch); ASSERT( surface ); // We need to make a copy, since lr.pBits will go away when we call UnlockRect(). RageSurface *SurfaceCopy = CreateSurface( surface->w, surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask ); RageSurfaceUtils::CopySurface( surface, SurfaceCopy ); delete surface; pCopy->UnlockRect(); pCopy->Release(); return SurfaceCopy; }
static bool d3d8_init_format_backbuffer(IDirect3DDevice8 *device) { IDirect3DSurface8 *backbuffer; D3DSURFACE_DESC desc; HRESULT hr; if (!d3d8_get_window_handle(device)) return false; backbuffer = d3d8_get_backbuffer(device); if (!backbuffer) return false; hr = backbuffer->GetDesc(&desc); backbuffer->Release(); if (FAILED(hr)) { hlog_hr("d3d8_init_format_backbuffer: Failed to get " "backbuffer descriptor", hr); return false; } data.d3d8_format = desc.Format; data.dxgi_format = d3d8_to_dxgi_format(desc.Format); data.cx = desc.Width; data.cy = desc.Height; return true; }
//! Regenerates the mip map levels of the texture. Useful after locking and //! modifying the texture void CD3D8Texture::regenerateMipMapLevels(void* mipmapData) { if (mipmapData) { core::dimension2du size = TextureSize; u32 level=0; do { if (size.Width>1) size.Width /=2; if (size.Height>1) size.Height /=2; ++level; IDirect3DSurface8* mipSurface = 0; HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface); if (FAILED(hr) || !mipSurface) { os::Printer::log("Could not get mipmap level", ELL_WARNING); return; } D3DSURFACE_DESC mipDesc; mipSurface->GetDesc(&mipDesc); D3DLOCKED_RECT miplr; // lock mipmap surface if (FAILED(mipSurface->LockRect(&miplr, NULL, 0))) { mipSurface->Release(); os::Printer::log("Could not lock texture", ELL_WARNING); return; } memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width); mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width; // unlock mipSurface->UnlockRect(); // release mipSurface->Release(); } while (size.Width != 1 || size.Height != 1); } else if (HasMipMaps) { // create mip maps. #ifndef _IRR_USE_D3DXFilterTexture_ // The D3DXFilterTexture function seems to get linked wrong when // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. // So mipmapgeneration is replaced with my own bad generation in d3d 8 when // compiling with both D3D 8 and 9. HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT , D3DX_DEFAULT ); if (FAILED(hr)) #endif createMipMaps(); } }
void CD3D8Texture::createRenderTarget() { TextureSize.Width = getTextureSizeFromSurfaceSize(TextureSize.Width); TextureSize.Height = getTextureSizeFromSurfaceSize(TextureSize.Height); // get backbuffer format to create the render target in the // same format IDirect3DSurface8* bb; D3DFORMAT d3DFormat = D3DFMT_A8R8G8B8; if (!FAILED(Device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &bb))) { D3DSURFACE_DESC desc; bb->GetDesc(&desc); d3DFormat = desc.Format; if (d3DFormat == D3DFMT_X8R8G8B8) d3DFormat = D3DFMT_A8R8G8B8; bb->Release(); } else { os::Printer::log("Could not create RenderTarget texture: could not get BackBuffer.", ELL_WARNING); return; } // create texture HRESULT hr; hr = Device->CreateTexture( TextureSize.Width, TextureSize.Height, 1, // mip map level count, we don't want mipmaps here D3DUSAGE_RENDERTARGET, d3DFormat, D3DPOOL_DEFAULT, &Texture); // get irrlicht format from D3D format ColorFormat = getColorFormatFromD3DFormat(d3DFormat); if (FAILED(hr)) os::Printer::log("Could not create render target texture"); }
// The D3DXFilterTexture function seems to get linked wrong when // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. // So mipmapgeneration is replaced with my own bad generation in d3d 8 when // compiling with both D3D 8 and 9. bool CD3D8Texture::createMipMaps(u32 level) { if (level==0) return true; IDirect3DSurface8* upperSurface = 0; IDirect3DSurface8* lowerSurface = 0; // get upper level HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface); if (FAILED(hr) || !upperSurface) { os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING); return false; } // get lower level hr = Texture->GetSurfaceLevel(level, &lowerSurface); if (FAILED(hr) || !lowerSurface) { os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING); upperSurface->Release(); return false; } D3DSURFACE_DESC upperDesc, lowerDesc; upperSurface->GetDesc(&upperDesc); lowerSurface->GetDesc(&lowerDesc); D3DLOCKED_RECT upperlr; D3DLOCKED_RECT lowerlr; // lock upper surface if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0))) { os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING); upperSurface->Release(); lowerSurface->Release(); return false; } // lock lower surface if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0))) { os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING); upperSurface->UnlockRect(); upperSurface->Release(); lowerSurface->Release(); return false; } if (upperDesc.Format != lowerDesc.Format) { os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING); } else { if (upperDesc.Format == D3DFMT_A1R5G5B5) copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, lowerDesc.Width, lowerDesc.Height, upperlr.Pitch, lowerlr.Pitch); else if (upperDesc.Format == D3DFMT_A8R8G8B8) copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, lowerDesc.Width, lowerDesc.Height, upperlr.Pitch, lowerlr.Pitch); else os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING); } bool result=true; // unlock if (FAILED(upperSurface->UnlockRect())) result=false; if (FAILED(lowerSurface->UnlockRect())) result=false; // release upperSurface->Release(); lowerSurface->Release(); if (!result || upperDesc.Width < 3 || upperDesc.Height < 3) return result; // stop generating levels // generate next level return createMipMaps(level+1); }
HRESULT myIDirect3DDevice8::copyDataToMemory(IDirect3DDevice8* device) { performanceDebugClock=clock(); //===============Memory Check======================= HRESULT hRes = S_FALSE; if(badMemory) { DXLOG("Sorry !Memory!"); return S_FALSE; } if(lpvMem==NULL)//Memory INIT; { badMemory=!setupSharedMemory(); if(badMemory) { DXLOG("Sorry !Memory!"); return S_FALSE; } } if(!isMemoryWritable()) { DXLOG("Memory not writable"); return S_FALSE; } //================FPS CHECK======================== if(lastRecordTime==0) { lastRecordTime=clock(); } else { long inteval=clock()-lastRecordTime; if(inteval<1000/MAXFPS) { //DXLOG("FPS QUICK"); return S_FALSE; } else { //DXLOG("FPS OK"); lastRecordTime=clock(); } } //================================================= IDirect3DSurface8 *pBackBuffer; if (FAILED(device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer))) { DXLOG("PBACKBUFEER"); return hRes; } D3DSURFACE_DESC surfaceDesc; pBackBuffer->GetDesc(&surfaceDesc); dumpSurfaceSettings(surfaceDesc); if(pSurfLocal==NULL) { DXLOG("SURFLOCAL CREATING"); hRes = device->CreateImageSurface(surfaceDesc.Width,// RWIDTH, surfaceDesc.Height,//RHEIGHT, surfaceDesc.Format, &pSurfLocal); if (FAILED(hRes)) { DXLOG("SURFLOCAL CREATING FAILED"); SafeRelease(pBackBuffer); return hRes; } } hRes=device->CopyRects(pBackBuffer,NULL,0,pSurfLocal,NULL); if (FAILED(hRes)) { DXLOG("COPY RECT FAILED"); SafeRelease(pBackBuffer); return hRes; } //device->GetRenderTargetData(pBackBuffer, pSurfLocal); D3DLOCKED_RECT lockedRect; if(FAILED(pSurfLocal->LockRect(&lockedRect, NULL, D3DLOCK_READONLY))) { DXLOG("Lock FAILED"); SafeRelease(pBackBuffer); return hRes; } //================BPP ADJUSTMENT===================== UINT bpp=4; int bppformat=-1; switch(surfaceDesc.Format) { case D3DFMT_R5G6B5: bpp = 2; bppformat=2; break; case D3DFMT_X1R5G5B5: bpp = 2; bppformat=3; break; case D3DFMT_A8R8G8B8: case D3DFMT_X8R8G8B8: bpp = 4; bppformat=1; break; default: bpp = 4; bppformat=1; break;//Most cards are gonna support A8R8G8B8/X8R8G8B8 anyway } UINT copySize=surfaceDesc.Width*surfaceDesc.Height*bpp; UINT surfaceHeight=surfaceDesc.Height; UINT surfaceWidth=surfaceDesc.Width; //======================Memory Copy============================= memcpy(lpvMem+(SHAREDMEMSIZE-RESERVEDMEMORY)/8,(void *)©Size,sizeof(UINT)); memcpy(lpvMem+(SHAREDMEMSIZE-RESERVEDMEMORY)/8+sizeof(UINT),(void *)&surfaceHeight,sizeof(UINT)); memcpy(lpvMem+(SHAREDMEMSIZE-RESERVEDMEMORY)/8+sizeof(UINT)*2,(void *)&surfaceWidth,sizeof(UINT)); memcpy(lpvMem+(SHAREDMEMSIZE-RESERVEDMEMORY)/8+sizeof(UINT)*3,(void *)&bppformat,sizeof(int)); memcpy(lpvMem, lockedRect.pBits,copySize); setMemoryReadable(); //=================================================== pSurfLocal->UnlockRect(); SafeRelease(pBackBuffer); LOGFILE(clock()-performanceDebugClock); return hRes; }