C++ D2D如何实现滚动屏幕功能?
我尝试在地图应用程序中使用Direct2D。但它比GDI慢得多,因为D2D绘制整个屏幕。 当用户滚动窗口时,GDI滚动视频缓冲区,只绘制屏幕的一小部分。这就是GDI比D2D更快的原因 我的问题是:C++ D2D如何实现滚动屏幕功能?,c++,drawrect,invalidation,direct2d,C++,Drawrect,Invalidation,Direct2d,我尝试在地图应用程序中使用Direct2D。但它比GDI慢得多,因为D2D绘制整个屏幕。 当用户滚动窗口时,GDI滚动视频缓冲区,只绘制屏幕的一小部分。这就是GDI比D2D更快的原因 我的问题是: 如何使用D2D滚动屏幕?(类似于ScrollWindow()) 我如何在D2D中只绘制屏幕的一小部分?(类似于invalidate()和GetClipBox()) 我找到了解决办法 有谁有更好的解决方案吗 我的例子是: D2D1::Matrix3x2F matrix; CPoint org(Get
- 如何使用D2D滚动屏幕?(类似于
)ScrollWindow()
- 我如何在D2D中只绘制屏幕的一小部分?(类似于
和invalidate()
)GetClipBox()
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
中。但是性能非常差。我找到了一个解决方案:使用“CDRenderTarget”。然后我们可以在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);
}
}
void CMFCGdi_D2D2View::OnDraw(CDC*pDC)
{
CMFCGdi_D2D2Doc*pDoc=GetDocument();
断言有效(pDoc);
如果(!pDoc)返回;
//TODO:在此处添加本机数据的绘图代码
#定义线宽3
正确无误;
pDC->GetClipBox(rcInvalid);
如果(rcInvalid.left==0和&rcInvalid.top==0)pDC->FillSolidRect(rcInvalid,RGB(255,0,0));
else pDC->FillSolidRect(rcInvalid,RGB(0,255,0));//可见重绘区域
正确的逻辑;
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.Dropellipse(CD2Delipse(CD2DPointF(150.0f,150.0f))、CD2DSizeF(100,100.)、m_pBlackBrush、线宽);
m_RenderTarget.绘制线(CD2DPointF(150.0f,150.0f),CD2DPointF(150.0f+100.0f*0.15425f,150.0f-100.0f*0.988f),
m_pBlackBrush,线宽);
m_RenderTarget.绘制线(CD2DPointF(150.0f,150.0f),CD2DPointF(150.0f+100.0f*0.525f,150.0f+100.0f*0.8509f),
m_pBlackBrush,线宽);
m_RenderTarget.绘制线(CD2DPointF(150.0f,150.0f),CD2DPointF(150.0f-100.0f*0.988f,150.0f-100.0f*0.15425f),
m_pBlackBrush,线宽);
HRESULT hr=m_RenderTarget.EndDraw();
如果(成功(hr))
{
//用GDI绘制饼图。
CPen黑色(PS_实线,线宽,RGB(255,0,0));
CPen*pOldPen=pDC->SelectObject(&penBlack);
pDC->椭圆(300、50、500、250);
pntArray1点[2];
pntArray1[0].x=400;
pntArray1[0].y=150;
pntArray1[1].x=静态_型铸造(400+100*0.15425);
pntArray1[1].y=静态铸型(150-100*0.9885);
pntArray2点[2];
pntArray2[0].x=400;
pntArray2[0].y=150;
pntArray2[1].x=静态_型铸造(400+100*0.525);
pntArray2[1],y=静态_铸造(150+100*0.8509);
第3点[2];
pntArray3[0].x=400;
pntArray3[0].y=150;
pntArray3[1].x=静态_型铸造(400-100*0.988);
pntArray3[1].y=静态铸型(150-100*0.15425);
pDC->多段线(pntArray1,2);
pDC->多段线(pntArray2,2);
pDC->多段线(pntArray3,2);
pDC->选择对象(&pOldPen);
}
}