int surface_save(int id, string filename) { draw_batch_flush(batch_flush_deferred); get_surfacev(surface,id,-1); string ext = enigma::image_get_format(filename); LPDIRECT3DSURFACE9 pDestBuffer; D3DSURFACE_DESC desc; surface.surf->GetDesc(&desc); d3ddev->CreateOffscreenPlainSurface( desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pDestBuffer, NULL ); d3ddev->GetRenderTargetData(surface.surf, pDestBuffer); D3DLOCKED_RECT rect; pDestBuffer->LockRect(&rect, NULL, D3DLOCK_READONLY); unsigned char* bitmap = static_cast<unsigned char*>(rect.pBits); pDestBuffer->UnlockRect(); int ret = enigma::image_save(filename, bitmap, desc.Width, desc.Height, desc.Width, desc.Height, false); pDestBuffer->Release(); return ret; }
LPDIRECT3DTEXTURE9 DX9RenderSystem::GetTextureCache( Texture* tex ) { TextureRC*& rc = (TextureRC*&)tex->mCache; if( !rc ) rc = new TextureRC( ); if( tex->IsDirty( ) ) { if( mCacheCount >= DX9MAXFRAMECACHE ) return 0; mCacheCount++; if( FAILED(D3DXCreateTexture( mDevice, tex->GetWidth( ), tex->GetHeight( ), 1, D3DUSAGE_DYNAMIC, (D3DFORMAT)tex->GetFormat( ), D3DPOOL_DEFAULT, &rc->mData )) ) { printf( "Failed to create Texture Cache :: Couldn't create surface\n" ); return 0; } LPDIRECT3DSURFACE9 surf; rc->mData->GetSurfaceLevel( 0, &surf ); D3DLOCKED_RECT rect; surf->LockRect( &rect, 0, 0 ); char* data = (char*)rect.pBits; memcpy( data, tex->GetBuffer( ), tex->GetBufferSize( ) ); surf->UnlockRect( ); D3DXSaveTextureToFile( "c:\\texdebug.png", D3DXIFF_PNG, rc->mData, 0 ); tex->SetDirty( false ); } return rc->mData; };
__forceinline bool CDecDXVA2::CopyFrame(LAVFrame *pFrame) { HRESULT hr; LPDIRECT3DSURFACE9 pSurface = (LPDIRECT3DSURFACE9)pFrame->data[3]; pFrame->format = LAVPixFmt_NV12; D3DSURFACE_DESC surfaceDesc; pSurface->GetDesc(&surfaceDesc); D3DLOCKED_RECT LockedRect; hr = pSurface->LockRect(&LockedRect, NULL, D3DLOCK_READONLY); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"pSurface->LockRect failed (hr: %X)", hr)); return false; } // Free AVFrame based buffers again FreeLAVFrameBuffers(pFrame); // Allocate memory buffers AllocLAVFrameBuffers(pFrame, LockedRect.Pitch); // Copy surface onto memory buffers CopyFrameNV12((BYTE *)LockedRect.pBits, pFrame->data[0], pFrame->data[1], surfaceDesc.Height, pFrame->height, LockedRect.Pitch); pSurface->UnlockRect(); return true; }
//============================================================== // <CImage>이미지를 로드하기: // 큰 표면을 작성하여 이미지를 로드해, // 이것을 256x256 픽셀씩 분할하여 텍스쳐 위에 복사함. // UpdateSurface나 StretchRect는 사용할 수 없으므로 // (D3DPOOL_DEFAULT의 텍스쳐에는 복사할 수 있으나 // 이 클래스에서는 D3DPOOL_MANAGED을 사용하기 때문에) // LockRect와 memcpy를 사용하여 복사함. void CImage::LoadFromFile(wstring file_name) { LPDIRECT3DSURFACE9 surface; D3DLOCKED_RECT slr; if (SUCCEEDED(Device->CreateOffscreenPlainSurface( XCount*256, YCount*256, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL)) ) { if (SUCCEEDED(D3DXLoadSurfaceFromFile( surface, NULL, NULL, file_name.c_str(), NULL, D3DX_FILTER_NONE, 0, NULL)) && SUCCEEDED(surface->LockRect( &slr, NULL, D3DLOCK_READONLY)) ) { for (int yc=0, i=0; yc<YCount; yc++) { for (int xc=0; xc<XCount; xc++, i++) { if (!Textures[i]) continue; D3DLOCKED_RECT tlr; if (SUCCEEDED(Textures[i]->LockRect(0, &tlr, NULL, 0))) { int x=xc*256, y=yc*256; for (int line=0; line<256; line++) { memcpy( (char*)tlr.pBits+tlr.Pitch*line, (char*)slr.pBits+x*4+slr.Pitch*(y+line), 256*4); } Textures[i]->UnlockRect(0); } } } surface->UnlockRect(); } surface->Release(); } }
//---------------------------------------------------------------------------------- // //---------------------------------------------------------------------------------- void InitGraphics(int width, int height ) { InitWindow(width, height); D3DPRESENT_PARAMETERS d3dp; ZeroMemory(&d3dp, sizeof(d3dp)); d3dp.BackBufferWidth = width; d3dp.BackBufferHeight = height; d3dp.BackBufferFormat = D3DFMT_X8R8G8B8; d3dp.BackBufferCount = 1; d3dp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dp.Windowed = TRUE; d3dp.hDeviceWindow = (HWND)GetHandle(); d3dp.EnableAutoDepthStencil = TRUE; d3dp.AutoDepthStencilFormat = D3DFMT_D16; #if __PerformanceCheckMode d3dp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; #endif g_d3d = Direct3DCreate9(D3D_SDK_VERSION); g_d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, (HWND) GetHandle(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dp, &g_d3d_device ); {// 市松模様の背景画像を作る g_d3d_device->CreateOffscreenPlainSurface( width, height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &g_d3d_clearing_image, NULL ); D3DLOCKED_RECT lockedRect; g_d3d_clearing_image->LockRect( &lockedRect, NULL, 0 ); CreateCheckeredPattern( width, height, (uint32_t*)lockedRect.pBits ); g_d3d_clearing_image->UnlockRect(); } g_renderer = ::EffekseerRendererDX9::Renderer::Create( g_d3d_device, 2000 ); g_renderer->SetProjectionMatrix( ::Effekseer::Matrix44().PerspectiveFovRH( 90.0f / 180.0f * 3.14f, (float)width / (float)height, 1.0f, 50.0f ) ); g_renderer->SetDistortingCallback( new DistortingCallback( (EffekseerRendererDX9::Renderer*)g_renderer, g_d3d_device, width, height ) ); g_manager->SetSpriteRenderer( g_renderer->CreateSpriteRenderer() ); g_manager->SetRibbonRenderer( g_renderer->CreateRibbonRenderer() ); g_manager->SetRingRenderer( g_renderer->CreateRingRenderer() ); g_manager->SetModelRenderer( g_renderer->CreateModelRenderer() ); g_manager->SetTrackRenderer( g_renderer->CreateTrackRenderer() ); g_manager->SetCoordinateSystem( ::Effekseer::CoordinateSystem::RH ); g_manager->SetTextureLoader( g_renderer->CreateTextureLoader() ); g_manager->SetModelLoader( g_renderer->CreateModelLoader() ); }
//--------------------------------- IP3DTexture* CP3DRenderer::TakeScreenShotTexture () { LPDIRECT3DSURFACE9 ScreenShotSurface = NULL; if (FAILED(g_pD3DDevice->GetBackBuffer (0, 0, D3DBACKBUFFER_TYPE_MONO, &ScreenShotSurface))) return NULL; // vytvor texturu CP3DTexture* pTex = new CP3DTexture(); pTex->Create(m_nWidth, m_nHeight, 1, TF_RGB8, false); P3DLOCKED_RECT pRect; pRect.pBits = NULL; // ziskej data ScreenShotSurface->LockRect((D3DLOCKED_RECT*)&pRect, NULL, 0); if (!pRect.pBits) goto quitHand; // ziskej cilova data P3DLOCKED_RECT pRectCil; pTex->GetSurfaceData(0, &pRectCil); // zkopiruj data if(pRectCil.Pitch==pRect.Pitch) // pokud se shoduji Pitch, je mozno pouzit rychle memcpy memcpy(pRectCil.pBits, pRect.pBits, sizeof(char)*m_nWidth*m_nHeight*4); else // pokud se neshoduji Pitch, musi se to udelat timto slozitym zpusobem { unsigned char* pSurface = static_cast<unsigned char*>(pRect.pBits); unsigned char* pTarSurface = static_cast<unsigned char*>(pRectCil.pBits); for (unsigned long r = 0; r < (unsigned int)m_nHeight; r++) { unsigned long dwIndexTar = r * pRectCil.Pitch; unsigned long dwIndex = r * pRect.Pitch; for (unsigned long c = 0; c < (unsigned int)m_nWidth; c++) { pTarSurface[dwIndexTar + c*4 + 0] = pSurface[dwIndex + c*4 + 0]; pTarSurface[dwIndexTar + c*4 + 1] = pSurface[dwIndex + c*4 + 1]; pTarSurface[dwIndexTar + c*4 + 2] = pSurface[dwIndex + c*4 + 2]; } } } // uzavri zdroj i cil ScreenShotSurface->UnlockRect(); pTex->SaveSurfaceData(); SAFE_RELEASE (ScreenShotSurface) // surface uz neni potreba return (IP3DTexture*)pTex; // vrat hotovou texturu quitHand: if(pTex) delete pTex; return NULL; }
HRESULT VertexObject::CreateTextureFromSurface(LPDIRECT3DSURFACE9 pSurface, RECT* pSrcRect, RECT* pDestRect, LPDIRECT3DTEXTURE9* ppTexture) { int width, height; RECT Src; D3DSURFACE_DESC surfDesc; pSurface->GetDesc(&surfDesc); if( !pSrcRect ) { width = surfDesc.Width; height = surfDesc.Height; Src.left = Src.top = 0; Src.right = width; Src.bottom = height; } else { width = pSrcRect->right - pSrcRect->left; // + 1; height = pSrcRect->bottom - pSrcRect->top; // + 1; Src = *pSrcRect; } D3DXCreateTexture(DDevice, width, height, 1, 0, surfDesc.Format, D3DPOOL_DEFAULT, ppTexture) ; // Retrieve the surface image of the texture. LPDIRECT3DSURFACE9 pTexSurface; LPDIRECT3DTEXTURE9 pTexture = *ppTexture; pTexture->GetLevelDesc(0, &surfDesc); pTexture->GetSurfaceLevel(0, &pTexSurface); // Create a clean surface to clear the texture with. LPDIRECT3DSURFACE9 pCleanSurface; D3DLOCKED_RECT lockRect; DDevice->CreateOffscreenPlainSurface( surfDesc.Width, surfDesc.Height, surfDesc.Format, D3DPOOL_DEFAULT, &pCleanSurface, NULL); pCleanSurface->LockRect(&lockRect, NULL, 0) ; memset((BYTE*)lockRect.pBits, 0, surfDesc.Height * lockRect.Pitch); pCleanSurface->UnlockRect() ; DDevice->UpdateSurface(pCleanSurface, NULL, pTexSurface, NULL); pCleanSurface->Release(); // Copy the image to the texture. POINT destPoint = { 0, 0 }; DDevice->UpdateSurface(pSurface, &Src, pTexSurface, &destPoint); pTexSurface->Release(); return S_OK; }
virtual const char* lock_framebuffer( void *& buffer, unsigned & pitch ) { if ( retry_count && !restore_objects() ) return "Lock failed"; lptex->GetLevelDesc(0, &d3dsd); if ( lptex->GetSurfaceLevel(0, &lpsurface) != D3D_OK ) return "Lock failed"; if ( lpsurface->LockRect(&d3dlr, 0, flags.lock) != D3D_OK ) return "Lock failed"; buffer = d3dlr.pBits; pitch = d3dlr.Pitch; return buffer != 0 ? 0 : "Lock failed"; }
bool EC_WidgetCanvas::Blit(const QImage &source, Ogre::TexturePtr destination) { #if defined(DIRECTX_ENABLED) && defined(WIN32) Ogre::HardwarePixelBufferSharedPtr pb = destination->getBuffer(); Ogre::D3D9HardwarePixelBuffer *pixelBuffer = dynamic_cast<Ogre::D3D9HardwarePixelBuffer*>(pb.get()); if (!pixelBuffer) return false; LPDIRECT3DSURFACE9 surface = pixelBuffer->getSurface(Ogre::D3D9RenderSystem::getActiveD3D9Device()); if (surface) { D3DSURFACE_DESC desc; HRESULT hr = surface->GetDesc(&desc); if (SUCCEEDED(hr)) { D3DLOCKED_RECT lock; HRESULT hr = surface->LockRect(&lock, 0, 0); if (SUCCEEDED(hr)) { const int bytesPerPixel = 4; ///\todo Count from Ogre::PixelFormat! const int sourceStride = bytesPerPixel * source.width(); if (lock.Pitch == sourceStride) memcpy(lock.pBits, source.bits(), sourceStride * source.height()); else for(int y = 0; y < source.height(); ++y) memcpy((u8*)lock.pBits + lock.Pitch * y, source.bits() + sourceStride * y, sourceStride); surface->UnlockRect(); } } } #else if (!destination->getBuffer().isNull()) { Ogre::Box update_box(0, 0, source.width(), source.height()); Ogre::PixelBox pixel_box(update_box, Ogre::PF_A8R8G8B8, (void*)source.bits()); destination->getBuffer()->blitFromMemory(pixel_box, update_box); } #endif return true; }
HRESULT CDxtexDoc::LoadVolumeSliceFromSurface(LPDIRECT3DVOLUME9 pVolume, UINT iSlice, LPDIRECT3DSURFACE9 psurf) { HRESULT hr; D3DSURFACE_DESC sd; D3DVOLUME_DESC vd; D3DLOCKED_RECT lr; D3DBOX boxSrc; D3DBOX boxDest; psurf->GetDesc(&sd); pVolume->GetDesc(&vd); boxSrc.Left = 0; boxSrc.Right = sd.Width; boxSrc.Top = 0; boxSrc.Bottom = sd.Height; boxSrc.Front = 0; boxSrc.Back = 1; boxDest.Left = 0; boxDest.Right = vd.Width; boxDest.Top = 0; boxDest.Bottom = vd.Height; boxDest.Front = iSlice; boxDest.Back = iSlice + 1; hr = psurf->LockRect(&lr, NULL, 0); if (FAILED(hr)) return hr; hr = D3DXLoadVolumeFromMemory(pVolume, NULL, &boxDest, lr.pBits, sd.Format, lr.Pitch, 0, NULL, &boxSrc, D3DX_DEFAULT, 0); psurf->UnlockRect(); return hr; }
int surface_getpixel_alpha(int id, int x, int y) { get_surfacev(surface,id,-1); if (x < 0) x = 0; if (y < 0) y = 0; if (x > surface->width || y > surface->height) return 0; d3dmgr->EndShapesBatching(); LPDIRECT3DSURFACE9 pBuffer = surface->surf; d3dmgr->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer); D3DSURFACE_DESC desc; pBackBuffer->GetDesc(&desc); D3DLOCKED_RECT rect; pBuffer->LockRect(&rect, NULL, D3DLOCK_READONLY); unsigned char* bitmap = static_cast<unsigned char*>(rect.pBits); unsigned offset = y * rect.Pitch + x * 4; int ret = bitmap[offset]; pBuffer->UnlockRect(); delete[] bitmap; return ret; }
// process and render media data int render() { try { if (m_shutdown) return 0; // capture user input once MODE mode = (m_mode == MODE_GPU_NV12) ? MODE_GPU_RGBA : m_mode; HRESULT r; LPDIRECT3DSURFACE9 pSurface; r = get_surface(&pSurface); if (FAILED(r)) { return -1; } m_timer.start(); switch (mode) { case MODE_CPU: { // process video frame on CPU D3DLOCKED_RECT memDesc = { 0, NULL }; RECT rc = { 0, 0, m_width, m_height }; r = pSurface->LockRect(&memDesc, &rc, 0); if (FAILED(r)) { return -1; } cv::Mat m(m_height, m_width, CV_8UC4, memDesc.pBits, memDesc.Pitch); if (m_demo_processing) { // blur D3D9 surface with OpenCV on CPU cv::blur(m, m, cv::Size(15, 15), cv::Point(-7, -7)); } r = pSurface->UnlockRect(); if (FAILED(r)) { return -1; } break; } case MODE_GPU_RGBA: { // process video frame on GPU cv::UMat u; cv::directx::convertFromDirect3DSurface9(pSurface, u); if (m_demo_processing) { // blur D3D9 surface with OpenCV on GPU with OpenCL cv::blur(u, u, cv::Size(15, 15), cv::Point(-7, -7)); } cv::directx::convertToDirect3DSurface9(u, pSurface); break; } } // switch m_timer.stop(); print_info(pSurface, mode, m_timer.time(Timer::UNITS::MSEC), m_oclDevName); // traditional DX render pipeline: // BitBlt surface to backBuffer and flip backBuffer to frontBuffer r = m_pD3D9Dev->StretchRect(pSurface, NULL, m_pBackBuffer, NULL, D3DTEXF_NONE); if (FAILED(r)) { return -1; } // present the back buffer contents to the display r = m_pD3D9Dev->Present(NULL, NULL, NULL, NULL); if (FAILED(r)) { return -1; } } // try catch (cv::Exception& e) { std::cerr << "Exception: " << e.what() << std::endl; return 10; } return 0; } // render()
HRESULT KG3DSelector::OnRender() { HRESULT hRetCode = E_FAIL; HRESULT hResult = E_FAIL; D3DLOCKED_RECT Rect; LPDIRECT3DSURFACE9 pResultColor = NULL; LPDIRECT3DSURFACE9 pStencilRT = NULL; D3DVIEWPORT9 vp; D3DVIEWPORT9 vpNew; KG3DRenderState RenderState; DWORD dwSelectIndex = 0xff; g_pd3dDevice->GetViewport(&vp); vpNew = vp; vpNew.X /= m_nScale; vpNew.Y /= m_nScale; vpNew.Width /= m_nScale; vpNew.Height /= m_nScale; m_dwIndex = 0;//Stencil Index清零 KG_PROCESS_SUCCESS(!m_vecModels.size()); hResult = g_pd3dDevice->GetRenderTarget(0, &m_pRTSave); KG_COM_PROCESS_ERROR(hResult); hResult = g_pd3dDevice->GetDepthStencilSurface(&m_pDepthSave); KG_COM_PROCESS_ERROR(hResult); hResult = m_pStencilRT->GetSurfaceLevel(0, &pStencilRT); KG_COM_PROCESS_ERROR(hResult); hResult = g_pd3dDevice->SetRenderTarget(0, pStencilRT); KG_COM_PROCESS_ERROR(hResult); hResult = g_pd3dDevice->SetDepthStencilSurface(m_pStencilDepth); KG_COM_PROCESS_ERROR(hResult); hResult = g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 1L); KG_COM_PROCESS_ERROR(hResult); g_pd3dDevice->SetViewport(&vpNew); RenderModelList(); if (0) { D3DXSaveTextureToFile("d:\\test.tga", D3DXIFF_TGA, m_pStencilRT, NULL); } hResult = g_pd3dDevice->SetTexture(0, m_pStencilRT); KG_COM_PROCESS_ERROR(hResult); g_pd3dDevice->SetTexture(1, NULL); hResult = g_pd3dDevice->SetDepthStencilSurface(NULL); KG_COM_PROCESS_ERROR(hResult); hResult = g_pd3dDevice->SetRenderTarget(0, m_pRT); KG_COM_PROCESS_ERROR(hResult); RenderState.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); float fU = float(m_MousePoint.x) / m_nWidth ; float fV = float(m_MousePoint.y) / m_nHeight; ScreenRect[0].vec2UV = D3DXVECTOR2(fU, fV); ScreenRect[1].vec2UV = D3DXVECTOR2(fU, fV); ScreenRect[2].vec2UV = D3DXVECTOR2(fU, fV); ScreenRect[3].vec2UV = D3DXVECTOR2(fU, fV); hResult = g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0f, 1L); KG_COM_PROCESS_ERROR(hResult); hResult = g_pd3dDevice->SetFVF(SelectorVertex::dwFVF); KG_COM_PROCESS_ERROR(hResult); RenderState.SetRenderState(D3DRS_FOGENABLE, FALSE); RenderState.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); RenderState.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); RenderState.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); RenderState.SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); hResult = g_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, ScreenRect, sizeof(SelectorVertex)); KG_COM_PROCESS_ERROR(hResult); hResult = m_pResult->GetSurfaceLevel(0, &pResultColor); KG_COM_PROCESS_ERROR(hResult); hResult = g_pd3dDevice->GetRenderTargetData(m_pRT, pResultColor); KG_COM_PROCESS_ERROR(hResult); hResult = pResultColor->LockRect(&Rect, NULL, 0); KG_COM_PROCESS_ERROR(hResult); BYTE *pBit = (BYTE*)Rect.pBits; dwSelectIndex = *(pBit + 2); pResultColor->UnlockRect(); KG_COM_PROCESS_ERROR(hResult); if (dwSelectIndex != 0xff) { _ASSERTE(dwSelectIndex < m_vecModels.size()); m_pSelectedModel = m_vecModels[dwSelectIndex]; } else { //模糊选择, 在所有的模型都没有精确选中的时候, 选中离镜头最近的那一个 D3DXVECTOR3 vec3CamPos; float fNear = 9999999999.f; DWORD dwNear = 0xffffffff; g_cGraphicsTool.GetCamera()->GetPosition(&vec3CamPos); for (size_t i = 0; i < m_vecModels.size(); i++) { D3DXVECTOR3 vec3Length = vec3CamPos - D3DXVECTOR3(m_vecModels[i]->m_matWorld._41, m_vecModels[i]->m_matWorld._42, m_vecModels[i]->m_matWorld._43); float fLength = vec3Length.x * vec3Length.x + vec3Length.y * vec3Length.y + vec3Length.z * vec3Length.z; if (fLength < fNear) { fNear = fLength; dwNear = static_cast<DWORD>(i); } } m_pSelectedModel = m_vecModels[dwNear]; } m_bSelected = TRUE; Exit1: hRetCode = S_OK; Exit0: if (!m_bSelected) { m_pSelectedModel = NULL; } m_vecModels.clear(); SAFE_RELEASE(pStencilRT); SAFE_RELEASE(pResultColor); if (m_pRTSave) { g_pd3dDevice->SetRenderTarget(0, m_pRTSave); } if (m_pDepthSave) { g_pd3dDevice->SetDepthStencilSurface(m_pDepthSave); g_pd3dDevice->SetViewport(&vp); } SAFE_RELEASE(pResultColor); SAFE_RELEASE(m_pRTSave); SAFE_RELEASE(m_pDepthSave); return hRetCode; }
//----------------------------------------------------------------------------- // Name: D3DUtil_SetDeviceCursor // Desc: Gives the D3D device a cursor with image and hotspot from hCursor. //----------------------------------------------------------------------------- HRESULT D3DUtil_SetDeviceCursor( LPDIRECT3DDEVICE9 pd3dDevice, HCURSOR hCursor, BOOL bAddWatermark ) { HRESULT hr = E_FAIL; ICONINFO iconinfo; BOOL bBWCursor; LPDIRECT3DSURFACE9 pCursorSurface = NULL; HDC hdcColor = NULL; HDC hdcMask = NULL; HDC hdcScreen = NULL; BITMAP bm; DWORD dwWidth; DWORD dwHeightSrc; DWORD dwHeightDest; COLORREF crColor; COLORREF crMask; UINT x; UINT y; BITMAPINFO bmi; COLORREF* pcrArrayColor = NULL; COLORREF* pcrArrayMask = NULL; DWORD* pBitmap; HGDIOBJ hgdiobjOld; ZeroMemory( &iconinfo, sizeof(iconinfo) ); if( !GetIconInfo( hCursor, &iconinfo ) ) goto End; if (0 == GetObject((HGDIOBJ)iconinfo.hbmMask, sizeof(BITMAP), (LPVOID)&bm)) goto End; dwWidth = bm.bmWidth; dwHeightSrc = bm.bmHeight; if( iconinfo.hbmColor == NULL ) { bBWCursor = TRUE; dwHeightDest = dwHeightSrc / 2; } else { bBWCursor = FALSE; dwHeightDest = dwHeightSrc; } // Create a surface for the fullscreen cursor if( FAILED( hr = pd3dDevice->CreateOffscreenPlainSurface( dwWidth, dwHeightDest, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCursorSurface, 0 ) ) ) { goto End; } pcrArrayMask = new DWORD[dwWidth * dwHeightSrc]; ZeroMemory(&bmi, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = dwWidth; bmi.bmiHeader.biHeight = dwHeightSrc; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; hdcScreen = GetDC( NULL ); hdcMask = CreateCompatibleDC( hdcScreen ); if( hdcMask == NULL ) { hr = E_FAIL; goto End; } hgdiobjOld = SelectObject(hdcMask, iconinfo.hbmMask); GetDIBits(hdcMask, iconinfo.hbmMask, 0, dwHeightSrc, pcrArrayMask, &bmi, DIB_RGB_COLORS); SelectObject(hdcMask, hgdiobjOld); if (!bBWCursor) { pcrArrayColor = new DWORD[dwWidth * dwHeightDest]; hdcColor = CreateCompatibleDC( hdcScreen ); if( hdcColor == NULL ) { hr = E_FAIL; goto End; } SelectObject(hdcColor, iconinfo.hbmColor); GetDIBits(hdcColor, iconinfo.hbmColor, 0, dwHeightDest, pcrArrayColor, &bmi, DIB_RGB_COLORS); } // Transfer cursor image into the surface D3DLOCKED_RECT lr; pCursorSurface->LockRect( &lr, NULL, 0 ); pBitmap = (DWORD*)lr.pBits; for( y = 0; y < dwHeightDest; y++ ) { for( x = 0; x < dwWidth; x++ ) { if (bBWCursor) { crColor = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x]; crMask = pcrArrayMask[dwWidth*(dwHeightSrc-1-y) + x]; } else { crColor = pcrArrayColor[dwWidth*(dwHeightDest-1-y) + x]; crMask = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x]; } if (crMask == 0) pBitmap[dwWidth*y + x] = 0xff000000 | crColor; else pBitmap[dwWidth*y + x] = 0x00000000; // It may be helpful to make the D3D cursor look slightly // different from the Windows cursor so you can distinguish // between the two when developing/testing code. When // bAddWatermark is TRUE, the following code adds some // small grey "D3D" characters to the upper-left corner of // the D3D cursor image. if( bAddWatermark && x < 12 && y < 5 ) { // 11.. 11.. 11.. .... CCC0 // 1.1. ..1. 1.1. .... A2A0 // 1.1. .1.. 1.1. .... A4A0 // 1.1. ..1. 1.1. .... A2A0 // 11.. 11.. 11.. .... CCC0 const WORD wMask[5] = { 0xccc0, 0xa2a0, 0xa4a0, 0xa2a0, 0xccc0 }; if( wMask[y] & (1 << (15 - x)) ) { pBitmap[dwWidth*y + x] |= 0xff808080; } } } } pCursorSurface->UnlockRect(); // Set the device cursor if( FAILED( hr = pd3dDevice->SetCursorProperties( iconinfo.xHotspot, iconinfo.yHotspot, pCursorSurface ) ) ) { goto End; } hr = S_OK; End: if( iconinfo.hbmMask != NULL ) DeleteObject( iconinfo.hbmMask ); if( iconinfo.hbmColor != NULL ) DeleteObject( iconinfo.hbmColor ); if( hdcScreen != NULL ) ReleaseDC( NULL, hdcScreen ); if( hdcColor != NULL ) DeleteDC( hdcColor ); if( hdcMask != NULL ) DeleteDC( hdcMask ); SAFE_DELETE_ARRAY( pcrArrayColor ); SAFE_DELETE_ARRAY( pcrArrayMask ); SAFE_RELEASE( pCursorSurface ); return hr; }
/// Load a texture from a proper DDSFile instance. bool GFXD3D9TextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds) { PROFILE_SCOPE(GFXD3D9TextureManager_loadTextureDDS); GFXD3D9TextureObject *texture = static_cast<GFXD3D9TextureObject*>(aTexture); // Fill the texture... for( int i = 0; i < aTexture->mMipLevels; i++ ) { PROFILE_SCOPE(GFXD3DTexMan_loadSurface); LPDIRECT3DSURFACE9 surf = NULL; D3D9Assert(texture->get2DTex()->GetSurfaceLevel( i, &surf ), "Failed to get surface"); #if defined(TORQUE_OS_XENON) XGTEXTURE_DESC surfDesc; dMemset(&surfDesc, 0, sizeof(XGTEXTURE_DESC)); XGGetSurfaceDesc(surf, &surfDesc); RECT srcRect; srcRect.top = srcRect.left = 0; srcRect.bottom = dds->getHeight(i); srcRect.right = dds->getWidth(i); D3DXLoadSurfaceFromMemory(surf, NULL, NULL, dds->mSurfaces[0]->mMips[i], (D3DFORMAT)MAKELINFMT(GFXD3D9TextureFormat[dds->mFormat]), dds->getSurfacePitch(i), NULL, &srcRect, false, 0, 0, D3DX_FILTER_NONE, 0); #else GFXD3D9Device* dev = static_cast<GFXD3D9Device *>(GFX); if (dev->isD3D9Ex()) { RECT r; r.top = r.left = 0; r.bottom = dds->getHeight(i); r.right = dds->getWidth(i); D3DXLoadSurfaceFromMemory(surf, NULL, NULL, dds->mSurfaces[0]->mMips[i], GFXD3D9TextureFormat[dds->mFormat], dds->getSurfacePitch(i), NULL, &r, D3DX_DEFAULT, 0); } else { D3DLOCKED_RECT lockedRect; D3D9Assert( surf->LockRect( &lockedRect, NULL, 0 ), "Failed to lock surface level for load" ); AssertFatal( dds->mSurfaces.size() > 0, "Assumption failed. DDSFile has no surfaces." ); if ( dds->getSurfacePitch( i ) != lockedRect.Pitch ) { // Do a row-by-row copy. U32 srcPitch = dds->getSurfacePitch( i ); U32 srcHeight = dds->getHeight(); U8* srcBytes = dds->mSurfaces[0]->mMips[i]; U8* dstBytes = (U8*)lockedRect.pBits; for (U32 i = 0; i<srcHeight; i++) { dMemcpy( dstBytes, srcBytes, srcPitch ); dstBytes += lockedRect.Pitch; srcBytes += srcPitch; } surf->UnlockRect(); surf->Release(); return true; } dMemcpy( lockedRect.pBits, dds->mSurfaces[0]->mMips[i], dds->getSurfaceSize(i) ); surf->UnlockRect(); } #endif surf->Release(); } return true; }
//----------------------------------------------------------------------------- // loadTexture - GBitmap //----------------------------------------------------------------------------- bool GFXD3D9TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *pDL) { PROFILE_SCOPE(GFXD3D9TextureManager_loadTexture); GFXD3D9TextureObject *texture = static_cast<GFXD3D9TextureObject*>(aTexture); #ifdef TORQUE_OS_XENON // If the texture is currently bound, it needs to be unbound before modifying it if( texture->getTex() && texture->getTex()->IsSet( mD3DDevice ) ) { mD3DDevice->SetTexture( 0, NULL ); mD3DDevice->SetTexture( 1, NULL ); mD3DDevice->SetTexture( 2, NULL ); mD3DDevice->SetTexture( 3, NULL ); mD3DDevice->SetTexture( 4, NULL ); mD3DDevice->SetTexture( 5, NULL ); mD3DDevice->SetTexture( 6, NULL ); mD3DDevice->SetTexture( 7, NULL ); } #endif // Check with profiler to see if we can do automatic mipmap generation. const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true); // Helper bool const bool isCompressedTexFmt = aTexture->mFormat >= GFXFormatDXT1 && aTexture->mFormat <= GFXFormatDXT5; GFXD3D9Device* dev = static_cast<GFXD3D9Device *>(GFX); // Settings for mipmap generation U32 maxDownloadMip = pDL->getNumMipLevels(); U32 nbMipMapLevel = pDL->getNumMipLevels(); if( supportsAutoMips && !isCompressedTexFmt ) { maxDownloadMip = 1; nbMipMapLevel = aTexture->mMipLevels; } // Fill the texture... for( int i = 0; i < maxDownloadMip; i++ ) { LPDIRECT3DSURFACE9 surf = NULL; D3D9Assert(texture->get2DTex()->GetSurfaceLevel( i, &surf ), "Failed to get surface"); D3DLOCKED_RECT lockedRect; #ifdef TORQUE_OS_XENON // On the 360, doing a LockRect doesn't work like it does with untiled memory // so instead swizzle into some temporary memory, and then later use D3DX // to do the upload properly. FrameTemp<U8> swizzleMem(pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()); lockedRect.pBits = (void*)~swizzleMem; #else U32 waterMark = 0; if (!dev->isD3D9Ex()) surf->LockRect( &lockedRect, NULL, 0 ); else { waterMark = FrameAllocator::getWaterMark(); lockedRect.pBits = static_cast<void*>(FrameAllocator::alloc(pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel())); } #endif switch( texture->mFormat ) { case GFXFormatR8G8B8: { PROFILE_SCOPE(Swizzle24_Upload); AssertFatal( pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed" ); GFX->getDeviceSwizzle24()->ToBuffer( lockedRect.pBits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel() ); } break; case GFXFormatR8G8B8A8: case GFXFormatR8G8B8X8: { PROFILE_SCOPE(Swizzle32_Upload); GFX->getDeviceSwizzle32()->ToBuffer( lockedRect.pBits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel() ); } break; default: { // Just copy the bits in no swizzle or padding PROFILE_SCOPE(SwizzleNull_Upload); AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch" ); dMemcpy( lockedRect.pBits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel() ); } } #ifdef TORQUE_OS_XENON RECT srcRect; srcRect.bottom = pDL->getHeight(i); srcRect.top = 0; srcRect.left = 0; srcRect.right = pDL->getWidth(i); D3DXLoadSurfaceFromMemory(surf, NULL, NULL, ~swizzleMem, (D3DFORMAT)MAKELINFMT(GFXD3D9TextureFormat[pDL->getFormat()]), pDL->getWidth(i) * pDL->getBytesPerPixel(), NULL, &srcRect, false, 0, 0, D3DX_FILTER_NONE, 0); #else if (!dev->isD3D9Ex()) surf->UnlockRect(); else { RECT srcRect; srcRect.top = 0; srcRect.left = 0; srcRect.right = pDL->getWidth(i); srcRect.bottom = pDL->getHeight(i); D3DXLoadSurfaceFromMemory(surf, NULL, NULL, lockedRect.pBits, GFXD3D9TextureFormat[pDL->getFormat()], pDL->getBytesPerPixel() * pDL->getWidth(i), NULL, &srcRect, D3DX_DEFAULT, 0); FrameAllocator::setWaterMark(waterMark); } #endif surf->Release(); } return true; }
bool CScreenshotSurface::capture() { #ifdef HAS_DX LPDIRECT3DSURFACE9 lpSurface = NULL, lpBackbuffer = NULL; g_graphicsContext.Lock(); if (g_application.IsPlayingVideo()) { #ifdef HAS_VIDEO_PLAYBACK g_renderManager.SetupScreenshot(); #endif } g_application.RenderNoPresent(); if (FAILED(g_Windowing.Get3DDevice()->CreateOffscreenPlainSurface(g_Windowing.GetWidth(), g_Windowing.GetHeight(), D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &lpSurface, NULL))) return false; if (FAILED(g_Windowing.Get3DDevice()->GetRenderTarget(0, &lpBackbuffer))) return false; // now take screenshot if (SUCCEEDED(g_Windowing.Get3DDevice()->GetRenderTargetData(lpBackbuffer, lpSurface))) { D3DLOCKED_RECT lr; D3DSURFACE_DESC desc; lpSurface->GetDesc(&desc); if (SUCCEEDED(lpSurface->LockRect(&lr, NULL, D3DLOCK_READONLY))) { m_width = desc.Width; m_height = desc.Height; m_stride = lr.Pitch; m_buffer = new unsigned char[m_height * m_stride]; memcpy(m_buffer, lr.pBits, m_height * m_stride); lpSurface->UnlockRect(); } else { CLog::Log(LOGERROR, "%s LockRect failed", __FUNCTION__); } } else { CLog::Log(LOGERROR, "%s GetBackBuffer failed", __FUNCTION__); } lpSurface->Release(); lpBackbuffer->Release(); g_graphicsContext.Unlock(); #elif defined(HAS_GL) || defined(HAS_GLES) g_graphicsContext.BeginPaint(); if (g_application.IsPlayingVideo()) { #ifdef HAS_VIDEO_PLAYBACK g_renderManager.SetupScreenshot(); #endif } g_application.RenderNoPresent(); #ifndef HAS_GLES glReadBuffer(GL_BACK); #endif //get current viewport GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); m_width = viewport[2] - viewport[0]; m_height = viewport[3] - viewport[1]; m_stride = m_width * 4; unsigned char* surface = new unsigned char[m_stride * m_height]; //read pixels from the backbuffer #if HAS_GLES == 2 glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)surface); #else glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)surface); #endif g_graphicsContext.EndPaint(); //make a new buffer and copy the read image to it with the Y axis inverted m_buffer = new unsigned char[m_stride * m_height]; for (int y = 0; y < m_height; y++) { #ifdef HAS_GLES // we need to save in BGRA order so XOR Swap RGBA -> BGRA unsigned char* swap_pixels = surface + (m_height - y - 1) * m_stride; for (int x = 0; x < m_width; x++, swap_pixels+=4) { std::swap(swap_pixels[0], swap_pixels[2]); } #endif memcpy(m_buffer + y * m_stride, surface + (m_height - y - 1) *m_stride, m_stride); } delete [] surface; #else //nothing to take a screenshot from return false; #endif return true; }
STDMETHODIMP CLAVSubtitleConsumer::ProcessFrame(LAVFrame *pFrame) { CheckPointer(m_pProvider, E_FAIL); HRESULT hr = S_OK; LPDIRECT3DSURFACE9 pSurface = nullptr; // Wait for the requested frame m_evFrame.Wait(); if (m_SubtitleFrame != nullptr) { int count = 0; if (FAILED(m_SubtitleFrame->GetBitmapCount(&count))) { count = 0; } if (count == 0) { SafeRelease(&m_SubtitleFrame); return S_FALSE; } BYTE *data[4] = {0}; ptrdiff_t stride[4] = {0}; LAVPixelFormat format = pFrame->format; int bpp = pFrame->bpp; if (pFrame->format == LAVPixFmt_DXVA2) { // Copy the surface, if required if (!(pFrame->flags & LAV_FRAME_FLAG_BUFFER_MODIFY)) { IMediaSample *pOrigSample = (IMediaSample *)pFrame->data[0]; LPDIRECT3DSURFACE9 pOrigSurface = (LPDIRECT3DSURFACE9)pFrame->data[3]; hr = m_pLAVVideo->GetD3DBuffer(pFrame); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"CLAVSubtitleConsumer::ProcessFrame: getting a new D3D buffer failed")); } else { IMediaSample *pNewSample = (IMediaSample *)pFrame->data[0]; pSurface = (LPDIRECT3DSURFACE9)pFrame->data[3]; IDirect3DDevice9 *pDevice = nullptr; if (SUCCEEDED(hr = pSurface->GetDevice(&pDevice))) { hr = pDevice->StretchRect(pOrigSurface, nullptr, pSurface, nullptr, D3DTEXF_NONE); if (SUCCEEDED(hr)) { pFrame->flags |= LAV_FRAME_FLAG_BUFFER_MODIFY|LAV_FRAME_FLAG_DXVA_NOADDREF; pOrigSurface = nullptr; // Release the surface, we only want to hold a ref on the media buffer pSurface->Release(); } SafeRelease(&pDevice); } if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"CLAVSubtitleConsumer::ProcessFrame: processing d3d buffer failed, restoring previous buffer")); pNewSample->Release(); pSurface->Release(); pFrame->data[0] = (BYTE *)pOrigSample; pFrame->data[3] = (BYTE *)pOrigSurface; } } } pSurface = (LPDIRECT3DSURFACE9)pFrame->data[3]; D3DSURFACE_DESC surfaceDesc; pSurface->GetDesc(&surfaceDesc); D3DLOCKED_RECT LockedRect; hr = pSurface->LockRect(&LockedRect, nullptr, 0); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"pSurface->LockRect failed (hr: %X)", hr)); SafeRelease(&m_SubtitleFrame); return E_FAIL; } data[0] = (BYTE *)LockedRect.pBits; data[1] = data[0] + (surfaceDesc.Height * LockedRect.Pitch); stride[0] = LockedRect.Pitch; stride[1] = LockedRect.Pitch; format = LAVPixFmt_NV12; bpp = 8; } else { if (!(pFrame->flags & LAV_FRAME_FLAG_BUFFER_MODIFY)) { CopyLAVFrameInPlace(pFrame); } memcpy(&data, &pFrame->data, sizeof(pFrame->data)); memcpy(&stride, &pFrame->stride, sizeof(pFrame->stride)); } RECT videoRect; ::SetRect(&videoRect, 0, 0, pFrame->width, pFrame->height); RECT subRect; m_SubtitleFrame->GetOutputRect(&subRect); ULONGLONG id; POINT position; SIZE size; const uint8_t *rgbData; int pitch; for (int i = 0; i < count; i++) { if (FAILED(m_SubtitleFrame->GetBitmap(i, &id, &position, &size, (LPCVOID *)&rgbData, &pitch))) { DbgLog((LOG_TRACE, 10, L"GetBitmap() failed on index %d", i)); break; } ProcessSubtitleBitmap(format, bpp, videoRect, data, stride, subRect, position, size, rgbData, pitch); } if (pSurface) pSurface->UnlockRect(); SafeRelease(&m_SubtitleFrame); return S_OK; } return S_FALSE; }
int Lines::draw(LPDIRECT3DSURFACE9 pBackSurf) { HRESULT hr; D3DLOCKED_RECT LockedRect;//locked area of display memory(buffer really) we are drawing to DWORD* pData; int dx, dy, sx, sy, err, e2, i, iend; //lock the back buffer, so we can edit the pixels hr = pBackSurf->LockRect(&LockedRect, NULL, 0); if (FAILED(hr)) { Errors::SetError(TEXT("Lines::draw Could not lock the back buffer")); } pData = (DWORD*)(LockedRect.pBits); //line from (100, 100) // to (200, 400) for (auto& line : lines) { i = line->x + line->y * LockedRect.Pitch / 4; //starting point iend = i + line->dx + line->dy * LockedRect.Pitch / 4; //ending point dx = abs(line->dx); // pixels travelled in x dy = abs(line->dy); // pixels traveled in y sx = line->dx > 0 ? 1 : -1; // +1 if going right, -1 if going left or vertical sy = line->dy > 0 ? 1 : -1; // +1 if going up, -1 if going down or horizontal err = (dx>dy ? dx : -dy) / 2;// TODO: figure out what's going on. for (;;) { pData[i] = colorFinal; if (i == iend) //below the pixel assignment to ensure both endpoints get colored. break; e2 = err; if (e2 > -dx) { err -= dy; i += sx; } if (e2 < dy) { err += dx; i += sy * LockedRect.Pitch / 4; } } } if (tempLine != NULL) { i = tempLine->x + tempLine->y * LockedRect.Pitch / 4; //starting point iend = i + tempLine->dx + tempLine->dy * LockedRect.Pitch / 4; //ending point dx = abs(tempLine->dx); // pixels travelled in x dy = abs(tempLine->dy); // pixels traveled in y sx = tempLine->dx > 0 ? 1 : -1; // +1 if going right, -1 if going left or vertical sy = tempLine->dy > 0 ? 1 : -1; // +1 if going up, -1 if going down or horizontal err = (dx>dy ? dx : -dy) / 2;// TODO: figure out what's going on. for (;;) { pData[i] = colorTemp; if (i == iend) //below the pixel assignment to ensure both endpoints get colored. break; e2 = err; if (e2 > -dx) { err -= dy; i += sx; } if (e2 < dy) { err += dx; i += sy * LockedRect.Pitch / 4; } } } pBackSurf->UnlockRect(); pData = 0; return S_OK; }
bool Lighting::CreateNormalizationCubeMap(LPDIRECT3DDEVICE9 Device, unsigned long Size) { HRESULT Hr; unsigned long i,x,y; LPDIRECT3DSURFACE9 CubeMapFace; D3DXVECTOR3 N; float W,H; unsigned long *Pixel; D3DLOCKED_RECT Lock; if(FAILED(Hr = Device->CreateCubeTexture(Size,1,0,D3DFMT_X8R8G8B8, D3DPOOL_MANAGED,&m_CubeNormal,NULL))) { return(false); } for(i=0; i < 6; i++) { m_CubeNormal->GetCubeMapSurface((D3DCUBEMAP_FACES)i,0,&CubeMapFace); Hr = CubeMapFace->LockRect(&Lock,NULL,0); if(FAILED(Hr)) { return(false); } Pixel = (unsigned long *)Lock.pBits; for(y = 0; y < Size; y++) { H = (float)y / (float)(Size - 1); H = (H * 2.0f) - 1.0f; for(x = 0; x < Size; x++) { W = (float)x / (float)(Size - 1); W = (W * 2.0f) - 1.0f; switch(i) { case D3DCUBEMAP_FACE_POSITIVE_X: N.x = +1.0f; N.y = -H; N.z = -W; break; case D3DCUBEMAP_FACE_NEGATIVE_X: N.x = -1.0f; N.y = -H; N.z = +W; break; case D3DCUBEMAP_FACE_POSITIVE_Y: N.x = +W; N.y = +1.0f; N.z = +H; break; case D3DCUBEMAP_FACE_NEGATIVE_Y: N.x = +W; N.y = -1.0f; N.z = -H; break; case D3DCUBEMAP_FACE_POSITIVE_Z: N.x = +W; N.y = -H; N.z = +1.0f; break; case D3DCUBEMAP_FACE_NEGATIVE_Z: N.x = -W; N.y = -H; N.z = -1.0f; break; } D3DXVec3Normalize(&N,&N); *Pixel++ = VectorToRGBA(&N); } } CubeMapFace->UnlockRect(); CubeMapFace->Release(); } return(true); }
void VideoCompressor::AddFrame(LPDIRECT3DSURFACE9 Surface, const Vec2i &Start, double TimeInSeconds) #endif { if(_Clock != NULL) { TimeInSeconds = _Clock->Elapsed(); } _Sample->SetSampleTime( LONGLONG( TimeInSeconds * 10000000.0 ) ); BYTE *BufferData; HRESULT hr = _Buffer->Lock(&BufferData, NULL, NULL); PersistentAssert(SUCCEEDED(hr), "_Buffer->Lock failed"); D3DSURFACE_DESC Desc; D3DLOCKED_RECT LockedRect; D3DAlwaysValidate(Surface->GetDesc(&Desc), "GetDesc"); PersistentAssert(Desc.Format == D3DFMT_A8R8G8B8 || Desc.Format == D3DFMT_X8R8G8B8, "Invalid surface format"); D3DAlwaysValidate(Surface->LockRect(&LockedRect, NULL, 0), "LockRect"); const UINT VideoWidth = _Width; const UINT VideoHeight = _Height; const UINT BufferPitch = sizeof(RGBColor) * VideoWidth; Vec2i CorrectedStart = Start; if(CorrectedStart.x < 0) { CorrectedStart.x = 0; } if(CorrectedStart.x + VideoWidth > Desc.Width) { CorrectedStart.x = Desc.Width - VideoWidth; } if(CorrectedStart.y < 0) { CorrectedStart.y = 0; } if(CorrectedStart.y + VideoHeight > Desc.Height) { CorrectedStart.y = Desc.Height - VideoHeight; } bool SizingCorrect = (CorrectedStart.x >= 0 && CorrectedStart.x + VideoWidth <= Desc.Width ) && (CorrectedStart.y >= 0 && CorrectedStart.y + VideoHeight <= Desc.Height); if(!SizingCorrect) { for(UINT y = 0; y < VideoHeight; y++) { memset(BufferData + y * BufferPitch, 0, BufferPitch); } } else if(Desc.Format == D3DFMT_A8R8G8B8 || Desc.Format == D3DFMT_X8R8G8B8) { for(UINT y = 0; y < VideoHeight; y++) { RGBColor *RowStart = (RGBColor *)((BYTE*)LockedRect.pBits + (y + CorrectedStart.y) * LockedRect.Pitch); memcpy(BufferData + (VideoHeight - 1 - y) * BufferPitch, RowStart + CorrectedStart.x, BufferPitch); //for(UINT x = 0; x < _Width; x++) //{ // (*this)[y][x] = RowStart[x]; //} } } D3DAlwaysValidate(Surface->UnlockRect(), "UnlockRect"); _Buffer->Unlock(); hr = _Writer->WriteSample(0, _Sample); PersistentAssert(SUCCEEDED(hr), "WriteSample failed"); }
HRESULT CDxtexDoc::LoadAlphaIntoSurface(CString& strPath, LPDIRECT3DSURFACE9 psurf) { HRESULT hr; D3DSURFACE_DESC sd; LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev(); LPDIRECT3DTEXTURE9 ptexAlpha; LPDIRECT3DSURFACE9 psurfAlpha; LPDIRECT3DSURFACE9 psurfTarget; psurf->GetDesc(&sd); // Load the alpha BMP into psurfAlpha, a new A8R8G8B8 surface hr = D3DXCreateTextureFromFileEx(pd3ddev, strPath, sd.Width, sd.Height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &ptexAlpha); hr = ptexAlpha->GetSurfaceLevel(0, &psurfAlpha); // Copy the target surface into an A8R8G8B8 surface hr = pd3ddev->CreateOffscreenPlainSurface(sd.Width, sd.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &psurfTarget, NULL); hr = D3DXLoadSurfaceFromSurface(psurfTarget, NULL, NULL, psurf, NULL, NULL, D3DX_DEFAULT, 0); // Fill in the alpha channels of psurfTarget based on the blue channel of psurfAlpha D3DLOCKED_RECT lrSrc; D3DLOCKED_RECT lrDest; hr = psurfAlpha->LockRect(&lrSrc, NULL, D3DLOCK_READONLY); hr = psurfTarget->LockRect(&lrDest, NULL, 0); DWORD xp; DWORD yp; DWORD* pdwRowSrc = (DWORD*)lrSrc.pBits; DWORD* pdwRowDest = (DWORD*)lrDest.pBits; DWORD* pdwSrc; DWORD* pdwDest; DWORD dwAlpha; LONG dataBytesPerRow = 4 * sd.Width; for (yp = 0; yp < sd.Height; yp++) { pdwSrc = pdwRowSrc; pdwDest = pdwRowDest; for (xp = 0; xp < sd.Width; xp++) { dwAlpha = *pdwSrc << 24; *pdwDest &= 0x00ffffff; *pdwDest |= dwAlpha; pdwSrc++; pdwDest++; } pdwRowSrc += lrSrc.Pitch / 4; pdwRowDest += lrDest.Pitch / 4; } psurfAlpha->UnlockRect(); psurfTarget->UnlockRect(); // Copy psurfTarget back into real surface hr = D3DXLoadSurfaceFromSurface(psurf, NULL, NULL, psurfTarget, NULL, NULL, D3DX_DEFAULT, 0); // Release allocated interfaces ReleasePpo(&psurfTarget); ReleasePpo(&psurfAlpha); ReleasePpo(&ptexAlpha); return S_OK; }
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; }