Как D2D реализует функцию экрана прокрутки?

Я пытался использовать Direct2D в нашем приложении карты. Но это намного медленнее, чем GDI, потому что D2D рисует весь экран.
Когда пользователь прокручивает окно, GDI прокручивает видео буфер и ТОЛЬКО рисует небольшую часть экрана. Вот почему GDI быстрее, чем D2D.

Мои вопросы:

  • Как D2D экран прокрутки? (Похожий на ScrollWindow())
  • Как мне нарисовать только небольшую часть экрана в D2D? (Похожий на InvalidateRect() а также GetClipBox())

Я нашел решение в
Как прокрутить содержимое окна с помощью 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, Но производительность очень плохая.

0

Решение

Я нашел одно решение: используя «CDCRenderTarget». Затем мы можем использовать функции scroll / GetClipBox () в CScrollView.

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]