DirectX — Как эффективно визуализировать небольшой спрайт в Direct3D / C ++ в большом окне (DWM)?

Я реализую пользовательский курсор в DirectX / C ++, который рисуется в прозрачном окне в верхней части рабочего стола.

Я раздели его до основной пример. Магия выполнения Direct3D на DWM основана на этом статья о проекте Code

Проблема состоит в том, что при использовании очень большого окна (например, 2560×1440) в качестве основы для визуализации DirectX, оно будет давать до 40% загрузки графического процессора в соответствии с GPU-Z. Даже если я показываю только статический спрайт 128×128 или вообще ничего. Если я использую область, такую ​​как 256×256, загрузка графического процессора составляет около 1-3%.

По сути, этот цикл заставит GPU сходить с ума по большому окну, в то время как он плавно движется по маленькому окну:

while(true) {
g_pD3DDevice->PresentEx(NULL, NULL, NULL, NULL, NULL);
Sleep(10);
}

Похоже, что он перерисовывает весь экран независимо от того, что-то меняется или нет, я прав? Могу ли я сказать Direct3D перерисовывать только те детали, которые необходимо обновить?

РЕДАКТИРОВАТЬ:
Я нашел способ сообщить Direct3D для рендеринга определенной части, предоставив информацию о грязном регионе RGNDATA для PresentEx. Теперь загрузка графического процессора составляет 1% вместо 20-40%.

    std::vector<RECT> dirtyRects;

//Fill dirtyRects with previous and new cursor boundaries

DWORD size = dirtyRects.size() * sizeof(RECT)+sizeof(RGNDATAHEADER);

RGNDATA *rgndata = NULL;

rgndata = (RGNDATA *)HeapAlloc(GetProcessHeap(), 0, size);RECT* pRectInitial = (RECT*)rgndata->Buffer;
RECT rectBounding = dirtyRects[0];

for (int i = 0; i < dirtyRects.size(); i++)
{
RECT rectCurrent = dirtyRects[i];
rectBounding.left = min(rectBounding.left, rectCurrent.left);
rectBounding.right = max(rectBounding.right, rectCurrent.right);
rectBounding.top = min(rectBounding.top, rectCurrent.top);
rectBounding.bottom = max(rectBounding.bottom, rectCurrent.bottom);

*pRectInitial = dirtyRects[i];
pRectInitial++;
}

//preparing rgndata header
RGNDATAHEADER  header;
header.dwSize = sizeof(RGNDATAHEADER);
header.iType = RDH_RECTANGLES;
header.nCount = dirtyRects.size();
header.nRgnSize = dirtyRects.size() * sizeof(RECT);
header.rcBound.left = rectBounding.left;
header.rcBound.top = rectBounding.top;
header.rcBound.right = rectBounding.right;
header.rcBound.bottom = rectBounding.bottom;

rgndata->rdh = header;

// Update display
g_pD3DDevice->PresentEx(NULL, NULL, NULL, rgndata, 0);

Но это то, чего я не понимаю. Это даст только 1% загрузки графического процессора, если я добавлю следующее

    SetLayeredWindowAttributes(hWnd, 0, 180, LWA_ALPHA);

В любом случае, я хочу, чтобы он был прозрачным, и это хорошо, но вместо этого через некоторое время я получаю некоторые странные эффекты. Чем заметнее, тем быстрее я двигаю курсор. Откуда это? Это выглядит как изображение. Я уверен, что я установил грязные каноны совершенно точно.

разрывающий

Вышеупомянутые разрывы, кажется, отличаются от компьютера к компьютеру.

0

Решение

Задача ещё не решена.

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


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