Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[13.58.137.218] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Если DrawSquare() пишу в уже существующем моём главном while, но там выполняется много действий, то идёт постоянное мерцание этого квадрата!
Если делать отдельно, то мерцаний меньше, но они есть. +кушает сильно процц. Я не силён в рисовании BitBlt, подскажите как нарисовать квадрат который в моём коде, но что-бы без мерцаний и не сильно кушал проц.. Код: #include <windows.h> using namespace std; void DrawSquare() { HWND aHwnd = GetDesktopWindow(); HDC aHdc = GetDC(aHwnd); HDC hcDevice = CreateCompatibleDC(aHdc); HBITMAP hcBitmapDevice = CreateCompatibleBitmap(aHdc, 2, 2); HGDIOBJ bufBm = (HBITMAP)SelectObject(hcDevice, hcBitmapDevice); for (int x = 1920 / 2.5; x < 1920 - (1920 / 2.5); x++) for (int y = 1080 / 3.5; y < (1080 / 3.5) + 2; y++) //вверх { BitBlt(aHdc, x, y, 2, 2, hcDevice, 0, 0, SRCCOPY); } for (int xx = 1920 / 2.5; xx < 1920 - (1920 / 2.5); xx++) for (int yy = 1080 - (1080 / 2.1); yy < (1080 - (1080 / 2.1)) + 2; yy++) //низ { BitBlt(aHdc, xx, yy, 2, 2, hcDevice, 0, 0, SRCCOPY); } for (int xx = 1920 / 2.5; xx < (1920 / 2.5) + 2; xx++) for (int yy = 1080 / 3.5; yy < 1080 - (1080 / 2.1); yy++) //левая сторона { BitBlt(aHdc, xx, yy, 2, 2, hcDevice, 0, 0, SRCCOPY); } for (int xx = 1920 - (1920 / 2.5); xx < (1920 - (1920 / 2.5)) + 2; xx++) for (int yy = 1080 / 3.5; yy < 1080 - (1080 / 2.1); yy++) //правая сторона { BitBlt(aHdc, xx, yy, 2, 2, hcDevice, 0, 0, SRCCOPY); } ReleaseDC(aHwnd, aHdc); DeleteDC(aHdc); DeleteDC(hcDevice); DeleteObject(hcBitmapDevice); DeleteObject(bufBm); } int main() { while (true) { DrawSquare(); } system("pause"); return 0; } |
Сообщ.
#2
,
|
|
|
Ну очевидно же: нарисовать всё в memDC(в памяти), а потом одним выводом BitBlt'а залупить сие на экран.
|
Сообщ.
#3
,
|
|
|
Цитата Славян @ Ну очевидно же: нарисовать всё в memDC(в памяти), а потом одним выводом BitBlt'а залупить сие на экран. Это как? если так, то нечего не получается: BitBlt([B]hcDevice[/B], x, y, 2, 2, [B]hcDevice[/B], 0, 0, SRCCOPY); |
Сообщ.
#4
,
|
|
|
Цитата Sawella @ Я не силён в рисовании BitBlt, подскажите как нарисовать квадрат который в моём коде, но что-бы без мерцаний и не сильно кушал проц.. Сценарий использования BitBlt примерно следующий: - Создаёшь контекст, связанный с bitmap (у тебя это сделано, не знаю насколько правильно) - Рисуешь в этом контексте то, что тебе нужно. В твоём случае что-то типа LineTo(hcDevice, ...... - Копируешь содержимое контекста в контекст окна при помощи BitBlt (Один раз!) |
Сообщ.
#5
,
|
|
|
Цитата Sawella @ Если DrawSquare() пишу в уже существующем моём главном while, но там выполняется много действий, то идёт постоянное мерцание этого квадрата! Если делать отдельно, то мерцаний меньше, но они есть. +кушает сильно процц. Я не силён в рисовании BitBlt, подскажите как нарисовать квадрат который в моём коде, но что-бы без мерцаний и не сильно кушал проц.. Код: #include <windows.h> using namespace std; void DrawSquare() { HWND aHwnd = GetDesktopWindow(); HDC aHdc = GetDC(aHwnd); HDC hcDevice = CreateCompatibleDC(aHdc); HBITMAP hcBitmapDevice = CreateCompatibleBitmap(aHdc, 2, 2); HGDIOBJ bufBm = (HBITMAP)SelectObject(hcDevice, hcBitmapDevice); for (int x = 1920 / 2.5; x < 1920 - (1920 / 2.5); x++) for (int y = 1080 / 3.5; y < (1080 / 3.5) + 2; y++) //вверх { BitBlt(aHdc, x, y, 2, 2, hcDevice, 0, 0, SRCCOPY); } for (int xx = 1920 / 2.5; xx < 1920 - (1920 / 2.5); xx++) for (int yy = 1080 - (1080 / 2.1); yy < (1080 - (1080 / 2.1)) + 2; yy++) //низ { BitBlt(aHdc, xx, yy, 2, 2, hcDevice, 0, 0, SRCCOPY); } for (int xx = 1920 / 2.5; xx < (1920 / 2.5) + 2; xx++) for (int yy = 1080 / 3.5; yy < 1080 - (1080 / 2.1); yy++) //левая сторона { BitBlt(aHdc, xx, yy, 2, 2, hcDevice, 0, 0, SRCCOPY); } for (int xx = 1920 - (1920 / 2.5); xx < (1920 - (1920 / 2.5)) + 2; xx++) for (int yy = 1080 / 3.5; yy < 1080 - (1080 / 2.1); yy++) //правая сторона { BitBlt(aHdc, xx, yy, 2, 2, hcDevice, 0, 0, SRCCOPY); } ReleaseDC(aHwnd, aHdc); DeleteDC(aHdc); DeleteDC(hcDevice); DeleteObject(hcBitmapDevice); DeleteObject(bufBm); } int main() { while (true) { DrawSquare(); } system("pause"); return 0; } Дак у тя вызов draw крутиться в бесконечном цикле |
Сообщ.
#6
,
|
|
|
Цитата Sawella @ но что-бы без мерцаний и не сильно кушал проц.. Попробуй так: #include <windows.h> using namespace std; HWND aHwnd = NULL; HDC aHdc = NULL; HDC hcDevice = NULL; HBITMAP hcBitmapDevice =NULL; HGDIOBJ bufBm = NULL; HBRUSH brush = NULL; COLORREF color = RGB(0,0,255); int x = 0; int y = 0; int dxdc = 500; int dydc = 300; int deltay = 4; int deltax = 4; void DrawSquare() { BitBlt(aHdc, x, y, dxdc, deltay, hcDevice, 0, 0, SRCCOPY); BitBlt(aHdc, x, y, deltax, dydc, hcDevice, 0, 0, SRCCOPY); BitBlt(aHdc, x, y+dydc-deltay, dxdc, deltay, hcDevice, 0, 0, SRCCOPY); BitBlt(aHdc, x+dxdc-deltax, y, deltax, dydc, hcDevice, 0, 0, SRCCOPY); } int main() { aHwnd = ::GetDesktopWindow(); RECT rc; ::GetWindowRect (aHwnd, &rc); x = ((rc.right - rc.left) - dxdc)/2; y = ((rc.bottom - rc.top) - dydc)/2; aHdc = ::GetDC(aHwnd); hcDevice = ::CreateCompatibleDC(aHdc); hcBitmapDevice = ::CreateCompatibleBitmap(aHdc, dxdc, dydc); bufBm = (HBITMAP)::SelectObject(hcDevice, hcBitmapDevice); brush = ::CreateSolidBrush (color); ::SelectObject (hcDevice, brush); ::PatBlt(hcDevice,0,0,dxdc,dydc,PATCOPY); // закрасить hcDevice кистью brush // while (true) for(int i=0;i<1000;++i) { DrawSquare(); ::Sleep(10); } ReleaseDC(aHwnd, aHdc); DeleteDC(aHdc); DeleteDC(hcDevice); DeleteObject(hcBitmapDevice); DeleteObject(bufBm); DeleteObject(brush); } |
Сообщ.
#7
,
|
|
|
Не очень понятно, как это может избавить от мерцания. Не проще ли просто нарисовать четыре линии?
|
Сообщ.
#8
,
|
|
|
Цитата ЫукпШ @ Попробуй так: Спасибо, за пример, но мерцания всё равно есть. |
Сообщ.
#9
,
|
|
|
Цитата Sawella @ Цитата ЫукпШ @ Попробуй так: Спасибо, за пример, но мерцания всё равно есть. А у меня - нет. Добавлено Цитата Олег М @ Не очень понятно, как это может избавить от мерцания. Не проще ли просто нарисовать четыре линии? автор хотел с BitBlt. Это более общий случай - возможно, имеются и дальнейшие планы. |
Сообщ.
#10
,
|
|
|
Цитата ЫукпШ @ А у меня - нет. Если я рисую на приложении например браузер и мышкой быстро скролить, то квадрат мерцает иногда. Вообщем буду пробовать как написали выше, т.к надо просто нарисовать статично без постоянных вызовов. p.s и если я draw пишу в свой главный while то мерцает постоянно, и почему вы решили делать с for? ведь после числа 1000 и.т.д. оно прекратится. |
Сообщ.
#11
,
|
|
|
Цитата Sawella @ Спасибо, за пример, но мерцания всё равно есть Чтобы не было мерцаний bitblt должен быть один. А там – четыре! Кроме того у окна должны быть установлены определенные флаги, чтоб оно не стирало содержимое при перерисовке. |
Сообщ.
#12
,
|
|
|
Цитата Sawella @ Цитата ЫукпШ @ А у меня - нет. Если я рисую на приложении например браузер и мышкой быстро скролить, то квадрат мерцает иногда. Вообщем буду пробовать как написали выше, т.к надо просто нарисовать статично без постоянных вызовов. С трудом понимаю, что ты хочешь сделать. В примере производится рисование в окне деск-топа. Это "типа фокус", так обычные приложения не работают и смысла делать такие вещи просто нет. Добавлено Цитата Олег М @ Цитата Sawella @ Спасибо, за пример, но мерцания всё равно есть Чтобы не было мерцаний bitblt должен быть один. А там – четыре! А почему 1 - можно, а 4 нельзя ? Что за бред... |
Сообщ.
#13
,
|
|
|
Цитата ЫукпШ @ А почему 1 - можно, а 4 нельзя ? Что за бред... Потому что в том и смысл, чтобы вывести все изображение за один раз |
Сообщ.
#14
,
|
|
|
Цитата Олег М @ Цитата ЫукпШ @ А почему 1 - можно, а 4 нельзя ? Что за бред... Потому что в том и смысл, чтобы вывести все изображение за один раз Специального смысла такого нет. Этот "смысл" зависит от конкретных потребностей и логики конкретного приложения. Прямого отношения к видео-эффектам это не имеет. Мелькания будут заметны, если перерисовка будет занимать более ~20.8 [мс] (48 гц). --- Поэтому я резко уменьшил число BitBlt в циклах алгоритма автора. Для рисования отрезка прямой нет необходимости выводить отрезок малыми фрагментами (как сделал автор) - можно вывести весь отрезок целиком. Гарантий не было, но интуиция подсказывала, где проблема. |
Сообщ.
#15
,
|
|
|
Цитата ЫукпШ @ Специального смысла такого нет. Этот "смысл" зависит от конкретных потребностей и логики конкретного приложения. Прямого отношения к видео-эффектам это не имеет. Мелькания будут заметны, если перерисовка будет занимать более 48 [мс]. Ты работаешь в многозадачной системе. И в любом случае, когда вывод изображения не является атомарным, ты получишь мерцание. |