【问题标题】:How D2D implement scroll screen function?D2D如何实现滚动屏幕功能?
【发布时间】:2013-08-29 16:31:27
【问题描述】:

我尝试在我们的地图应用程序中使用 Direct2D。但它比 GDI 慢得多,因为 D2D 绘制整个屏幕。 当用户滚动窗口时,GDI 滚动视频缓冲区并且只绘制屏幕的一小部分。这就是 GDI 比 D2D 快的原因。

我的问题是:

  • D2D如何滚动屏幕?(类似于ScrollWindow()
  • 如何在 D2D 中只绘制一小部分屏幕?(类似于InvalidateRect()GetClipBox()

我找到了解决方案 How to scroll window contents using Direct2D api? 谁有更好的解决方案?

我的例子是:

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);

CScrollView。但是性能很差。

【问题讨论】:

    标签: c++ drawrect invalidation direct2d


    【解决方案1】:

    我找到了一种解决方案:使用“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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      相关资源
      最近更新 更多