HRESULT dxReadPixels(IDirect3DDevice9* Device, void* Buffer, bool& Minimised, int& Width, int& Height, D3DFORMAT Format) { IDirect3DSurface9* RenderTarget = nullptr; IDirect3DSurface9* DestTarget = nullptr; HRESULT result = Device->GetRenderTarget(0, &RenderTarget); if (result == S_OK) { if (Width == 0 || Height == 0 || Format == D3DFMT_UNKNOWN) { D3DSURFACE_DESC descriptor = {}; RenderTarget->GetDesc(&descriptor); Width = descriptor.Width; Height = descriptor.Height; Format = descriptor.Format; } HDC DC = nullptr; RenderTarget->GetDC(&DC); Minimised = IsIconic(WindowFromDC(DC)); RenderTarget->ReleaseDC(DC); result = Device->CreateOffscreenPlainSurface(Width, Height, Format, D3DPOOL_SYSTEMMEM, &DestTarget, nullptr); result = Device->GetRenderTargetData(RenderTarget, DestTarget); D3DLOCKED_RECT rect; DestTarget->LockRect(&rect, 0, D3DLOCK_READONLY); memcpy(Buffer, rect.pBits, Width * Height * 4); DestTarget->UnlockRect(); } SafeRelease(RenderTarget); SafeRelease(DestTarget); return result; }
void DxFlashViewer::UpdateTexture() { if(NULL == this->mViewerWnd) return; RECT rect = {0, 0, this->mViewerWidth, this->mViewerHeight}; IDirect3DSurface9* pSurface = NULL; this->mTexture->GetSurfaceLevel(0, &pSurface); if (NULL != pSurface) { HDC hdcTexture; HRESULT hr = pSurface->GetDC(&hdcTexture); if(FAILED(hr)) return; ::SetMapMode(hdcTexture, MM_TEXT); ::OleDraw(this->mFlashCtrl, DVASPECT_CONTENT, hdcTexture, &rect); pSurface->ReleaseDC(hdcTexture); pSurface->Release(); } }
bool CPicture::LoadTextureOverGDI(const std::string& fileName, int maxWidth, int maxHeight) { CleanUp(); int filenameSize; LPWSTR filenameWSTR; Gdiplus::Bitmap* pThumbnail = NULL; Gdiplus::PixelFormat pixelFormat; // File filenameSize = MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, fileName.c_str(), -1, 0, 0); filenameWSTR = (LPWSTR) malloc(filenameSize * sizeof(LPWSTR)); MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, fileName.c_str(), -1, filenameWSTR, filenameSize); // load with gdi++ Gdiplus::Bitmap imageBitmap(filenameWSTR); free (filenameWSTR); if ((maxWidth != -1) && (maxHeight != -1)) { if (maxWidth == -1) maxWidth = imageBitmap.GetWidth(); if (maxHeight == -1) maxHeight = imageBitmap.GetHeight(); float iWidthRelation = (float) imageBitmap.GetWidth() / maxWidth; float iHeightRelation = (float) imageBitmap.GetHeight() / maxHeight; if (imageBitmap.GetWidth() > imageBitmap.GetHeight()) { maxHeight = (long) (imageBitmap.GetHeight() / iWidthRelation); } else { maxWidth = (long) (imageBitmap.GetWidth() / iHeightRelation); } if ((maxWidth <= 128) && (maxHeight <= 128)) { pThumbnail = (Gdiplus::Bitmap*) imageBitmap.GetThumbnailImage(maxWidth, maxHeight, NULL, NULL); pixelFormat = pThumbnail->GetPixelFormat(); } else { pixelFormat = imageBitmap.GetPixelFormat(); } } else { maxWidth = imageBitmap.GetWidth(); maxHeight = imageBitmap.GetHeight(); pixelFormat = imageBitmap.GetPixelFormat(); } if (!this->CreateEmptyPixelFormat(maxWidth, maxHeight, pixelFormat)) { SallyAPI::System::CLogger* logger = SallyAPI::Core::CGame::GetLogger(); logger->Error("CPicture::LoadTextureOverGDI() CreateEmptyPixelFormat failed"); SafeDelete(pThumbnail); return false; } IDirect3DSurface9* surface = NULL; SallyAPI::Core::CTexture* texture = this->GetTexture(); if (texture == NULL) { SallyAPI::System::CLogger* logger = SallyAPI::Core::CGame::GetLogger(); logger->Error("CPicture::LoadTextureOverGDI() CTexture->GetTexture failed"); SafeDelete(pThumbnail); return false; } LPDIRECT3DTEXTURE9 d3dTexture = texture->GetTexture(); if (d3dTexture == NULL) { SallyAPI::System::CLogger* logger = SallyAPI::Core::CGame::GetLogger(); logger->Error("CPicture::LoadTextureOverGDI() LPDIRECT3DTEXTURE9->GetTexture failed"); SafeDelete(pThumbnail); return false; } D3DSURFACE_DESC pDesc; d3dTexture->GetLevelDesc(0, &pDesc); d3dTexture->GetSurfaceLevel(0, &surface); HDC hdc; surface->GetDC(&hdc); if (pThumbnail == NULL) { Gdiplus::Graphics graphics(hdc); graphics.DrawImage(&imageBitmap, 0, 0, pDesc.Width, pDesc.Height); } else { Gdiplus::Graphics graphics(hdc); graphics.DrawImage(pThumbnail, 0, 0, pDesc.Width, pDesc.Height); /* Gdiplus::Graphics graphics(pThumbnail); HDC dcThumbnail = graphics.GetHDC(); ::BitBlt(hdc, 0, 0, pDesc.Width, pDesc.Height, dcThumbnail, 0, 0, pThumbnail->GetWidth(), pThumbnail->GetHeight(), SRCCOPY); graphics.ReleaseHDC(dcThumbnail); */ } surface->ReleaseDC(hdc); surface->Release(); SafeDelete(pThumbnail); return true; }
//--------------------------------------------------------------------- void DrawFrame() { HRESULT hr; // Update flash movie if necessarily unsigned int numDirtyRects; const RECT* dirtyRects; if (g_flashPlayer->IsNeedUpdate(NULL, &dirtyRects, &numDirtyRects)) { IDirect3DTexture9* pTexToUpdate = g_texturesRotation[g_currentTexture]; if (++g_currentTexture == num_textures_in_rotation) g_currentTexture = 0; IDirect3DSurface9* pSrcSurface; hr = pTexToUpdate->GetSurfaceLevel(0, &pSrcSurface); assert(SUCCEEDED(hr)); HDC surfaceDC; hr = pSrcSurface->GetDC(&surfaceDC); assert(SUCCEEDED(hr)); // Draw flash frame g_flashPlayer->DrawFrame(surfaceDC); hr = pSrcSurface->ReleaseDC(surfaceDC); assert(SUCCEEDED(hr)); // Update our GUI texture IDirect3DSurface9* pDestSurface; hr = g_textureGUI->GetSurfaceLevel(0, &pDestSurface); assert(SUCCEEDED(hr)); for (unsigned int i = 0; i < numDirtyRects; ++i) { POINT destPoint = { dirtyRects[i].left, dirtyRects[i].top }; hr = g_device->UpdateSurface(pSrcSurface, dirtyRects + i, pDestSurface, &destPoint); assert(SUCCEEDED(hr)); } pDestSurface->Release(); pSrcSurface->Release(); } //--------------------------------------------------------------------- struct TLVERTEX { float x; float y; float z; float rhw; D3DCOLOR color; float u; float v; }; const DWORD D3DFVF_TLVERTEX = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1; float halfInvWindowWidth = 1.0f / g_windowWidth * 0.5f; float halfInvWindowHeight = 1.0f / g_windowHeight * 0.5f; // Create quad vertices TLVERTEX vertices[4]; vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0.0f; vertices[0].rhw = 1.0f; vertices[0].color = 0xFFFFFFFF; vertices[0].u = halfInvWindowWidth; vertices[0].v = halfInvWindowHeight; vertices[1].x = (float)g_windowWidth; vertices[1].y = 0; vertices[1].z = 0.0f; vertices[1].rhw = 1.0f; vertices[1].color = 0xFFFFFFFF; vertices[1].u = 1.0f + halfInvWindowWidth; vertices[1].v = halfInvWindowHeight; vertices[2].x = (float)g_windowWidth; vertices[2].y = (float)g_windowHeight; vertices[2].z = 0.0f; vertices[2].rhw = 1.0f; vertices[2].color = 0xFFFFFFFF; vertices[2].u = 1.0f + halfInvWindowWidth; vertices[2].v = 1.0f + halfInvWindowHeight; vertices[3].x = 0; vertices[3].y = (float)g_windowHeight; vertices[3].z = 0.0f; vertices[3].rhw = 1.0f; vertices[3].color = 0xFFFFFFFF; vertices[3].u = halfInvWindowWidth; vertices[3].v = 1.0f + halfInvWindowHeight; // Begin frame hr = g_device->BeginScene(); assert(SUCCEEDED(hr)); hr = g_device->Clear(0, NULL, D3DCLEAR_TARGET, 0xFF000000, 1.0f, 0); assert(SUCCEEDED(hr)); // Draw the quad hr = g_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); assert(SUCCEEDED(hr)); hr = g_device->SetRenderState(D3DRS_FOGENABLE, false); assert(SUCCEEDED(hr)); hr = g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true); assert(SUCCEEDED(hr)); // Use alpha channel in texture for alpha hr = g_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); assert(SUCCEEDED(hr)); hr = g_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); assert(SUCCEEDED(hr)); hr = g_device->SetTexture(0, g_textureGUI); assert(SUCCEEDED(hr)); hr = g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); assert(SUCCEEDED(hr)); hr = g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); assert(SUCCEEDED(hr)); hr = g_device->SetFVF(D3DFVF_TLVERTEX); assert(SUCCEEDED(hr)); hr = g_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, vertices, sizeof(TLVERTEX)); assert(SUCCEEDED(hr)); hr = g_device->EndScene(); assert(SUCCEEDED(hr)); hr = g_device->Present(NULL, NULL, NULL, NULL); assert(SUCCEEDED(hr)); }