📄 dx_viewport.cpp
字号:
IDirectDrawSurface *tmps = create_surface(); clear_surface(tmps, lib::color_t(0xff0000)); IDirectDrawSurface *s1, *s2; if (m_fstransition->is_outtrans()) { s1 = m_surface; s2 = m_fstr_surface; } else { s1 = m_fstr_surface; s2 = m_surface; } //draw(s1, ourrect, ourrect, false, tmps); // Determine blitter type and blend in the fg surface smil2::blitter_type bt = m_fstransition->get_blitter_type(); if (bt == smil2::bt_r1r2r3r4) { lib::rect src_rc_v = ourrect; lib::rect dst_rc_v = ourrect; clipto_r1r2r3r4(m_fstransition, src_rc_v, dst_rc_v); draw(s2, dst_rc_v, dst_rc_v, false, tmps); } else if (bt == smil2::bt_fade) { if (bits_size == 32) blt_blend32(ourrect, m_fstransition->get_progress(), s2, tmps); else if (bits_size == 24) blt_blend24(ourrect, m_fstransition->get_progress(), s2, tmps); else if (bits_size == 16) blt_blend16(ourrect, m_fstransition->get_progress(), s2, tmps); else draw(s2, ourrect, ourrect, false, tmps); } else { HRGN hrgn = NULL; switch (bt) { case smil2::bt_rect: hrgn = create_rect_region(m_fstransition); break; case smil2::bt_rectlist: hrgn = create_rectlist_region(m_fstransition); break; case smil2::bt_poly: hrgn = create_poly_region(m_fstransition); break; case smil2::bt_polylist: hrgn = create_polylist_region(m_fstransition); break; } HDC tmps_dc; HRESULT hr = tmps->GetDC(&tmps_dc); if (FAILED(hr)) { seterror("DirectDrawSurface::GetDC()", hr); return; } HDC s2_dc; hr = s2->GetDC(&s2_dc); if (FAILED(hr)) { seterror("DirectDrawSurface::GetDC()", hr); return; } if (hrgn) SelectClipRgn(tmps_dc, hrgn); int w, h; w = dst_rc.right - dst_rc.left; h = dst_rc.bottom - dst_rc.top; BitBlt(tmps_dc, dst_rc.left, dst_rc.top, w, h, s2_dc, dst_rc.left, dst_rc.top, SRCCOPY); tmps->ReleaseDC(tmps_dc); s2->ReleaseDC(s2_dc); } primary_Blt(m_primary_surface, to_screen_rc_ptr(dst_rc), tmps, &src_rc, flags, NULL); release_surface(tmps); } else { // Copy to screen primary_Blt(m_primary_surface, to_screen_rc_ptr(dst_rc), m_surface, &src_rc, flags, NULL); // Copy to backing store for posible fs transition later HRESULT hr = m_fstr_surface->Blt(&src_rc, m_surface, &src_rc, flags, NULL); if (FAILED(hr)) { seterror("viewport::redraw()/DirectDrawSurface::Blt() m_fstr_surface", hr); } }}void gui::dx::viewport::redraw(const lib::rect& rc) { if(!m_primary_surface || !m_surface) return; RECT src_rc = {rc.left(), rc.top(), rc.right(), rc.bottom()}; RECT dst_rc = {rc.left(), rc.top(), rc.right(), rc.bottom()}; // Convert dst to screen coordinates to_screen_rc_ptr(dst_rc); // Verify: if(IsRectEmpty(&src_rc) || IsRectEmpty(&dst_rc)) return; RECT vrc = {0, 0, m_width, m_height}; if(!IntersectRect(&src_rc, &src_rc, &vrc) || IsRectEmpty(&src_rc)) return; // Blit: lib::rect ourrect(lib::point(0,0), lib::size(m_width, m_height)); DWORD flags = DDBLT_WAIT; if (m_fstransition) { AM_DBG lib::logger::get_logger()->debug("viewport::redraw: Applying fullscreen transition"); // Create a temp surface, determine bg/fg surfaces and copy the background IDirectDrawSurface *tmps = create_surface(); clear_surface(tmps, lib::color_t(0x00ff00)); IDirectDrawSurface *s1, *s2; if (m_fstransition->is_outtrans()) { s1 = m_surface; s2 = m_fstr_surface; } else { s1 = m_fstr_surface; s2 = m_surface; } draw(s1, ourrect, ourrect, false, tmps); // Determine blitter type and blend in the fg surface smil2::blitter_type bt = m_fstransition->get_blitter_type(); if (bt == smil2::bt_r1r2r3r4) { lib::rect src_rc_v = ourrect; lib::rect dst_rc_v = ourrect; clipto_r1r2r3r4(m_fstransition, src_rc_v, dst_rc_v); draw(s2, dst_rc_v, dst_rc_v, false, tmps); } else if (bt == smil2::bt_fade) { if (bits_size == 32) blt_blend32(ourrect, m_fstransition->get_progress(), s2, tmps); else if (bits_size == 24) blt_blend24(ourrect, m_fstransition->get_progress(), s2, tmps); else if (bits_size == 16) blt_blend16(ourrect, m_fstransition->get_progress(), s2, tmps); else draw(s2, ourrect, ourrect, false, tmps); } else { HRGN hrgn = NULL; switch (bt) { case smil2::bt_rect: hrgn = create_rect_region(m_fstransition); break; case smil2::bt_rectlist: hrgn = create_rectlist_region(m_fstransition); break; case smil2::bt_poly: hrgn = create_poly_region(m_fstransition); break; case smil2::bt_polylist: hrgn = create_polylist_region(m_fstransition); break; } HDC tmps_dc; HRESULT hr = tmps->GetDC(&tmps_dc); if (FAILED(hr)) { seterror("DirectDrawSurface::GetDC()", hr); return; } HDC s2_dc; hr = s2->GetDC(&s2_dc); if (FAILED(hr)) { seterror("DirectDrawSurface::GetDC()", hr); return; } if (hrgn) SelectClipRgn(tmps_dc, hrgn); int w, h; w = src_rc.right - src_rc.left; h = src_rc.bottom - src_rc.top; BitBlt(tmps_dc, src_rc.left, src_rc.top, w, h, s2_dc, src_rc.left, src_rc.top, SRCCOPY); tmps->ReleaseDC(tmps_dc); s2->ReleaseDC(s2_dc); } primary_Blt(m_primary_surface, &dst_rc, tmps, &src_rc, flags, NULL); } else { // Copy to screen primary_Blt(m_primary_surface, &dst_rc, m_surface, &src_rc, flags, NULL); // Copy to backing store, for later use with transition // XXX Or should we copy the whole surface? HRESULT hr = m_fstr_surface->Blt(&src_rc, m_surface, &src_rc, flags, NULL); if (FAILED(hr)) { seterror("viewport::redraw()/DirectDrawSurface::Blt()", hr); } }}void gui::dx::viewport::schedule_redraw() {#ifdef DO_REDRAW_WITH_EVENTS ::InvalidateRect(m_hwnd, NULL, 0);#else redraw();#endif // DO_REDRAW_WITHOUT_EVENTS}void gui::dx::viewport::schedule_redraw(const lib::rect& rc) {#ifdef DO_REDRAW_WITH_EVENTS RECT src_rc = {rc.left(), rc.top(), rc.right(), rc.bottom()}; ::InvalidateRect(m_hwnd, &src_rc, 0);#else redraw(rc);#endif // DO_REDRAW_WITHOUT_EVENTS}// Clears the back buffer using this viewport bgd colorvoid gui::dx::viewport::clear() { if(!m_surface) return; DDBLTFX bltfx; memset(&bltfx, 0, sizeof(DDBLTFX)); bltfx.dwSize = sizeof(bltfx); bltfx.dwFillColor = m_ddbgd; RECT dst_rc = {0, 0, m_width, m_height}; HRESULT hr = m_surface->Blt(&dst_rc, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx); if (FAILED(hr)) { seterror(":viewport::clear/DirectDrawSurface::Blt()", hr); }}// Clears the specified back buffer rectangle using the provided color and taking into account any transitionvoid gui::dx::viewport::clear(const lib::rect& rc, lib::color_t clr, dx_transition *tr) { if(!m_surface) return; if(!tr) { clear(rc, clr, m_surface); return; } smil2::blitter_type bt = tr->get_blitter_type(); if(bt == smil2::bt_r1r2r3r4) { lib::rect rc_v = rc; clipto_r1r2r3r4(tr, rc_v, rc_v); clear(rc_v, clr, m_surface); return; } else if(bt == smil2::bt_fade) { IDirectDrawSurface* s1 = create_surface(); IDirectDrawSurface* s2 = create_surface(); if(!s1 || !s2) { RELEASE(s1); RELEASE(s2); clear(rc, clr, m_surface); return; } clear(rc, clr, s1); copy_bgd_to(s2, rc); HRESULT hr = S_OK; if(bits_size == 32) { hr = blt_blend32(rc, tr->get_progress(), s1, s2); draw_to_bgd(s2, rc, 0); } else if(bits_size == 24) { hr = blt_blend24(rc, tr->get_progress(), s1, s2); draw_to_bgd(s2, rc, 0); } else if(bits_size == 16) { hr = blt_blend16(rc, tr->get_progress(), s1, s2); draw_to_bgd(s2, rc, 0); } else { draw_to_bgd(s1, rc, 0); } if (FAILED(hr)) { seterror("blt_blendXX()", hr); } release_surface(s1); release_surface(s2); return; } HRGN hrgn = 0; switch(bt) { case smil2::bt_rect: hrgn = create_rect_region(tr); break; case smil2::bt_rectlist: hrgn = create_rectlist_region(tr); break; case smil2::bt_poly: hrgn = create_poly_region(tr); break; case smil2::bt_polylist: hrgn = create_polylist_region(tr); break; } if(!hrgn) { clear(rc, clr, m_surface); return; } else if(is_empty_region(hrgn)) { // nothing to paint return; } IDirectDrawSurface* s1 = create_surface(); clear(rc, clr, s1); OffsetRgn(hrgn, rc.left(), rc.top()); draw_to_bgd(s1, rc, hrgn); release_surface(s1); DeleteObject((HGDIOBJ)hrgn);}// Clears the specified surface rectangle using the provided colorvoid gui::dx::viewport::clear(const lib::rect& rc, lib::color_t clr, IDirectDrawSurface* dstview) { if(!dstview) return; DDBLTFX bltfx; memset(&bltfx, 0, sizeof(DDBLTFX)); bltfx.dwSize = sizeof(bltfx); bltfx.dwFillColor = convert(clr); RECT dstRC = {rc.left(), rc.top(), rc.right(), rc.bottom()}; // Verify: RECT vrc = {0, 0, m_width, m_height}; if(!IntersectRect(&dstRC, &dstRC, &vrc) || IsRectEmpty(&dstRC)) return; HRESULT hr = dstview->Blt(&dstRC, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx); if (FAILED(hr)) { seterror(":viewport::clear/DirectDrawSurface::Blt()", hr); }}// Clears a DD surface with the provided color.void gui::dx::viewport::clear_surface(IDirectDrawSurface* p, lib::color_t clr) { DDSURFACEDESC sd; memset(&sd, 0, sizeof(DDSURFACEDESC)); sd.dwSize = sizeof(DDSURFACEDESC); DDBLTFX bltfx; memset(&bltfx, 0, sizeof(DDBLTFX)); bltfx.dwSize = sizeof(bltfx); bltfx.dwFillColor = (clr == CLR_INVALID)?m_ddbgd:convert(clr); RECT dst_rc; set_rect(p, &dst_rc); HRESULT hr = p->Blt(&dst_rc, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx); if (FAILED(hr)) { seterror("DirectDrawSurface::Blt()", hr); }}// Draw the whole DD surface to the back buffer and destination rectanglevoid gui::dx::viewport::draw(IDirectDrawSurface* src, const lib::rect& dst_rc, bool keysrc) { if(!m_surface || !src) return; DWORD flags = DDBLT_WAIT; if(keysrc) flags |= DDBLT_KEYSRC; // Set srcRC to surf rect RECT srcRC; set_rect(src, &srcRC); RECT dstRC = {dst_rc.left(), dst_rc.top(), dst_rc.right(), dst_rc.bottom()}; // Verify: // Dest within viewport RECT vrc = {0, 0, m_width, m_height}; if(!IntersectRect(&dstRC, &dstRC, &vrc) || IsRectEmpty(&dstRC)) return; HRESULT hr = m_surface->Blt(&dstRC, src, &srcRC, flags, NULL); if (FAILED(hr)) { seterror(":viewport::clear/DirectDrawSurface::Blt()", hr); }}// Draw the src_rc of the DD surface to the back buffer and destination rectanglevoid gui::dx::viewport::draw(IDirectDrawSurface* src, const lib::rect& src_rc, const lib::rect& dst_rc, bool keysrc, dx_transition *tr) { if(!m_surface || !src) return; if(!tr) { draw(src, src_rc, dst_rc, keysrc, m_surface); return; } smil2::blitter_type bt = tr->get_blitter_type(); if(bt == smil2::bt_r1r2r3r4) {#ifdef XXXX // r.1.40 leads to #1619481 smil2::transition_blitclass_r1r2r3r4 *p = tr->get_as_r1r2r3r4_blitter(); r1r2r3r4_adapter *r1r2r3r4 = (r1r2r3r4_adapter*)p; assert(r1r2r3r4); // copy rectangle of old pixels away were the new ones go lib::rect old_src = r1r2r3r4->get_old_src_rect(); old_src.translate(r1r2r3r4->get_dst()->get_global_topleft()); lib::rect old_dst = r1r2r3r4->get_old_dst_rect(); old_dst.translate(r1r2r3r4->get_dst()->get_global_topleft()); draw(m_surface, old_src, old_dst, keysrc, m_surface); // copy new pixels in place of the old pixels lib::rect new_src = r1r2r3r4->get_src_rect(); lib::rect new_dst = r1r2r3r4->get_dst_rect(); lib::rect src_rc_v = src_rc; lib::rect dst_rc_v = dst_rc; src_rc_v &= new_src; dst_rc_v &= new_dst; dst_rc_v.w = src_rc_v.w; //XXXX draw(src, src_rc_v, dst_rc_v, keysrc, m_surface); #else /*XXXX*/// r.1.39 doesn't have the problem lib::rect src_rc_v = src_rc; lib::rect dst_rc_v = dst_rc; clipto_r1r2r3r4(tr, src_rc_v, dst_rc_v); draw(src, src_rc_v, dst_rc_v, keysrc, m_surface);#endif/*XXXX*/ return; } else if(bt == smil2::bt_fade) { IDirectDrawSurface* s1 = create_surface(); IDirectDrawSurface* s2 = create_surface(); if(!s1 || !s2) { RELEASE(s1); RELEASE(s2); draw(src, src_rc, dst_rc, keysrc, m_surface); return; } if(keysrc) copy_bgd_to(s1, dst_rc); draw(src, src_rc, dst_rc, keysrc, s1); copy_bgd_to(s2, dst_rc); HRESULT hr = S_OK; if(bits_size == 32) { hr = blt_blend32(dst_rc, tr->get_progress(), s1, s2); draw_to_bgd(s2, dst_rc, 0); } else if(bits_size == 24) { hr = blt_blend24(dst_rc, tr->get_progress(), s1, s2); draw_to_bgd(s2, dst_rc, 0); } else if(bits_size == 16) { hr = blt_blend16(dst_rc, tr->get_progress(), s1, s2); draw_to_bgd(s2, dst_rc, 0); } else { draw_to_bgd(s1, dst_rc, 0); } if (FAILED(hr)) { seterror("blt_blendXX()", hr); } release_surface(s1); release_surface(s2); return; } HRGN hrgn = 0; switch(bt) { case smil2::bt_rect: hrgn = create_rect_region(tr); break; case smil2::bt_rectlist: hrgn = create_rectlist_region(tr); break; case smil2::bt_poly: hrgn = create_poly_region(tr); break; case smil2::bt_polylist: hrgn = create_polylist_region(tr); break; } if(!hrgn) { draw(src, src_rc, dst_rc, keysrc, m_surface);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -