2013-08-29 7 views
0

지도 응용 프로그램에서 Direct2D를 사용하려고했습니다. 그러나 D2D가 전체 화면을 그리기 때문에 GDI보다 훨씬 느립니다. 사용자가 창을 스크롤하면 GDI가 비디오 버퍼를 스크롤하고 화면의 작은 부분 만 그립니다. 그래서 GDI가 D2D보다 빠릅니다.D2D가 스크롤 화면 기능을 구현하는 방법은 무엇입니까?

내 질문은 :

  • 어떻게 D2D 스크롤 화면? (ScrollWindow()과 유사)
  • 어떻게하면 D2D에 작은 화면 만 그릴 수 있습니까? 내가 How to scroll window contents using Direct2D api? 사람이 더 나은 솔루션이 있습니까에서 해결책을 발견

(InvalidateRect()GetClipBox() 유사)?

내 예는 다음과 같습니다 CScrollView에서

D2D1::Matrix3x2F matrix; 
CPoint org(GetDeviceScrollPosition()); 
FLOAT scaleW=(FLOAT)m_totalLog.cx/m_totalDev.cx; 
FLOAT scaleH=(FLOAT)m_totalLog.cy/m_totalDev.cy; 

if(scaleW > scaleH) scaleW = scaleH; 
matrix.SetProduct(D2D1::Matrix3x2F::Scale(scaleW, scaleH, D2D1::Point2F(0.0f, 0.0f)),  D2D1::Matrix3x2F::Translation((FLOAT)-org.x, (FLOAT)-org.y)); 
//"Scale Device Screen" * "Scroll Device Screen" 
pRenderTarget->SetTransform(matrix); 

. 그러나 성능은 매우 열악합니다.

답변

0

"CDCRenderTarget"을 사용하여 하나의 해결책을 찾았습니다. 그런 다음 CScrollView에서 scroll/GetClipBox() 함수를 사용할 수 있습니다.

void CMFCGdi_D2D2View::OnDraw(CDC* pDC) 
{ 
    CMFCGdi_D2D2Doc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
    if (!pDoc) return; 

    // TODO: add draw code for native data here 
    #define LINE_WIDTH 3 

    CRect rcInvalid; 
    pDC->GetClipBox(rcInvalid); 
    if(rcInvalid.left==0 && rcInvalid.top==0) pDC->FillSolidRect(rcInvalid, RGB(255,0,0)); 
    else pDC->FillSolidRect(rcInvalid, RGB(0, 255, 0)); //visible redraw area 

    CRect rcLogical; 
    GetClientRect(rcLogical); 
    rcLogical.bottom+=GetScrollPosition().y; 
    rcLogical.right+=GetScrollPosition().x; 

    m_RenderTarget.BindDC(*pDC, rcLogical); 
    m_RenderTarget.BeginDraw(); 
    m_RenderTarget.SetTransform(D2D1::Matrix3x2F::Identity()); 
    m_RenderTarget.DrawEllipse(CD2DEllipse(CD2DPointF(150.0f, 150.0f), CD2DSizeF(100., 100.)), m_pBlackBrush, LINE_WIDTH); 
    m_RenderTarget.DrawLine(CD2DPointF(150.0f, 150.0f), CD2DPointF(150.0f + 100.0f * 0.15425f, 150.0f - 100.0f * 0.988f), 
     m_pBlackBrush, LINE_WIDTH); 
    m_RenderTarget.DrawLine(CD2DPointF(150.0f, 150.0f), CD2DPointF(150.0f + 100.0f * 0.525f, 150.0f + 100.0f * 0.8509f), 
     m_pBlackBrush, LINE_WIDTH); 
    m_RenderTarget.DrawLine(CD2DPointF(150.0f, 150.0f), CD2DPointF(150.0f - 100.0f * 0.988f, 150.0f - 100.0f * 0.15425f), 
     m_pBlackBrush, LINE_WIDTH); 
    HRESULT hr = m_RenderTarget.EndDraw(); 

    if (SUCCEEDED(hr)) 
    { 
     // Draw the pie chart with GDI. 
     CPen penBlack(PS_SOLID, LINE_WIDTH, RGB(255, 0, 0)); 
     CPen* pOldPen = pDC->SelectObject(&penBlack); 

     pDC->Ellipse(300, 50, 500, 250); 

     POINT pntArray1[2]; 
     pntArray1[0].x = 400; 
     pntArray1[0].y = 150; 
     pntArray1[1].x = static_cast<LONG>(400 + 100 * 0.15425); 
     pntArray1[1].y = static_cast<LONG>(150 - 100 * 0.9885); 

     POINT pntArray2[2]; 
     pntArray2[0].x = 400; 
     pntArray2[0].y = 150; 
     pntArray2[1].x = static_cast<LONG>(400 + 100 * 0.525); 
     pntArray2[1].y = static_cast<LONG>(150 + 100 * 0.8509); 

     POINT pntArray3[2]; 
     pntArray3[0].x = 400; 
     pntArray3[0].y = 150; 
     pntArray3[1].x = static_cast<LONG>(400 - 100 * 0.988); 
     pntArray3[1].y = static_cast<LONG>(150 - 100 * 0.15425); 

     pDC->Polyline(pntArray1, 2); 
     pDC->Polyline(pntArray2, 2); 
     pDC->Polyline(pntArray3, 2); 

     pDC->SelectObject(&pOldPen); 
    } 
}