[VC++/WinAPI] Podwójne buforowanie

0

Witam. Kiedyś czytałem w Komputer Świat Expert jak zrobić podwójne buforowanie bez użycia OGL czy D3D... ale niestety nie mam juz tego numeru, a potrzebuje zlikwidowac migotanie obrazu. Zapewne cala sprawa ogranicza sie do przerzycenia jednego kontekstu w ktorym rysujemy do drugiego wlasciwego kontekstu urzadzenia... tylko jak to zrealizowac ? Bo chyba nie tak : hdc = hdcBuffor; ? Jak zrobić podwójne buforowanie ? (Visual C++)

0

Tworzysz nowy kontekst (CreateCompatibleDC) i bitmapę (CreateCompatibleBitmap). Nastepnie przypisujesz bitmapę nowemu kontekstowi (SelectObject). Podpinasz się pod komunikat WM_PAINT i wywalasz bitmape na ekran funkcją BitBlt. Poszukaj informacji o BeginPaint i EndPaint. Oczywiście pominąłem sprawe zmiany rozmiaru bufora ale to banał wiec dasz sobie radę.
That's all :)

0

Noo piekny opis. A co to ma wspolnego z podwojnym buforowaniem? :P

0

Noo piekny opis. A co to ma wspolnego z podwojnym buforowaniem?

Jak to co?:P

0

No przeciez ja sie o to zapytalem. Kazesz chlopakowi tworzyc bitmape, nowy kontekst, obsluge wm_paint. A gdzie w tym wszystkim podwojne buforowanie? Moze troszke kodu? ;)

0

No przeciez ja sie o to zapytalem. Kazesz chlopakowi tworzyc bitmape, nowy kontekst, obsluge wm_paint. A gdzie w tym wszystkim podwojne buforowanie? Moze troszke kodu?

Kodu nie pisałem bo nie miałem czasu i założyłem, że autor topiku mniej więcej wie o co w tym wszystkim chodzi, a jakby nie wiedział zawsze może się dopytać. Na razie rzuciłem nazwy funkcji i niech poszuka informacji na ich temat i pokombinuje.

0

hehe tak sie sklada ze to nie ma nic wspolnego z podwojnym buforowaniem... :) tak to sie robi normalnie przy wyswietlaniu bitmapy... a przy uzyciu funkcji BitBlt nastepuje przerzucanie jednego buforu do drugiego pixel po pixelu i jest widczone rysowanie obrazka, a nie o to chodzi. Chce zrobic tak zeby bufory byly zamieniane, gdy w drugim buforze rysunek zostanie namalowany to jest on przesylany do pierwszego bufora (zamieniany) itd. Nie wiem jak to sie dzieje ze przy zamianie buforow nie widac rysowania obrazka ale tak juz jest i chce cos takeigo zrobic ale nie wiem jak...

0

Wszystko pięknie, tylko o czym wy piszecie?

jagi: o co właściwie ci chodzi (pierwszy post niczego nie wyjaśniał... drugi też nie...) Napisz co chcesz osiągnąć, a nie jak zrobić coś co wg. ciebie nazywa się podwójnym buforowaniem, np. "wyświetlam animację tak i tak ale miga..." albo "rysuję kontrolkę tak i tak ale miga..."
O co chodziło w tym, ehm, "Komputer Świat Ekspercie" ??

Termin podwójne buforowanie zależy od kontekstu w jakim jest użyty, przy wyświetlaniu animacji chodzi o każdą technikę, w której podczas gdy jeden bufor jest wyświetlany, drugi jest rysowany, następnie drugi jest wyświetlany, a pierwszy jest rysowany. Jednak jest to możliwe, gdy mamy bezpośredni dostęp do pamięci w której rysujemy i możemy przełączyć urządzenie wyświetlające (kartę graficzną) tak aby pokazywała odpowiedni bufor, unikamy wtedy kopiowania pamięci [to oczywiście nie musi być aż tak proste...].

Bo jeśli chodzi ci o tzw. flicker-free drawing, można to rozwiązać właśnie przez DC w pamięci i kopiowanie przez BitBlt. Nie wiem dlaczego raz piszesz o "przesylaniu" i "zamienianiu", a potem nagle stwierdzasz, że to nie jest to o co ci chodzi...??
BitBlt nie kopiuje "po pixelu" tylko wykonuje BLock Transfer, który może być wspogany sprzętowo przez kartę graficzną.

No nie wiem czy można w łatwy sposób przez GDI "zamieniać" DC bez kopiowania...? :> Że niby przełączę kartę graficzną na inny obszar pamięci? :D

Znowu: "Chce zrobic tak zeby bufory byly zamieniane, gdy w drugim buforze rysunek zostanie namalowany to jest on przesylany do pierwszego bufora (zamieniany)" wskazuje na to, że sam do końca nie wiesz co chcesz osiągnąć... Przecież tu nie zamiany wyświetlanego DC, tylko kopiowanie do DC, czyli wracamy do rozwiązania z DC w pamięci RAM i kopiowaniu do DC wyświetlanego.

To się naprawdę tak robi, rysuje w RAMie, a następnie szybko przenosisz cały obraz do pamięci graficznej karty... W Windows oczywiście po drodze mamy GDI, ale kopiowanie (z dopalaczem :) ) i tak pozostaje bardzo szybkie...

Tylko co ty chcesz zrobić?

0

Częściowo masz rację ale ty mówisz o page flipping'u co nie zmienia faktu, że to też jest podwójne buforowanie. Założyłem, że chodzi ci o zwykłe okna więc podwójne buforowanie wykonuje się funkcją BitBlt. Z tego co mi wiadomo (być może się mylę) to page flipping jest możliwy tylko w trybie pełno-ekranowym.

... a przy uzyciu funkcji BitBlt nastepuje przerzucanie jednego buforu do drugiego pixel po pixelu i jest widczone rysowanie obrazka

Teoretycznie to prawda ale w praktyce nie ma to znaczenia. ;) - cała sztuczka polega na ukryciu czasochłonnego rysowania poza ekran a samo przerzucenie back-buffor'a na ekran jest procesem dość szybkim.

0

Dobra moze nie precyzyjnie sie wyslowilem ale nie wiedzialem ze mozna to rozumiec na dwa sposoby... Nie bede uzywal tych wszystkich fachowy terminow wiec wyjasnie to w ten sposob: chce uniknac migotoania obrazu przy "rysowaniu kolejnej klatki animacji"...

0
jagi napisał(a)

Dobra moze nie precyzyjnie sie wyslowilem ale nie wiedzialem ze mozna to rozumiec na dwa sposoby... Nie bede uzywal tych wszystkich fachowy terminow wiec wyjasnie to w ten sposob: chce uniknac migotoania obrazu przy "rysowaniu kolejnej klatki animacji"...

...i? Co dalej? Jak rysujesz? win API, VCL, jakaś biblioteka?? Dokładnie, choć sądze, że nadal nie wiesz sam co chcesz zrobić... sposób z DC w pamięci ci nie wystarcza? Co to za animacja? Jakieś obliczenia? Zrozum, że tu nikt nie jest wróżką, a jak nie opiszesz dokładnie takiego problemu to nie licz na sensowną odpowiedź..

0

Dobra widze ze musze dokladnie opisac o co chodzi :) To bedzie tak... napisalem "animacja" w cudzyslowiu, bo zamierzam kiedys takze animacje buforowac ale na razie to chodzi mi o takie cos. Mam wyswietlona bitmape za pomoca BitBlt i gdy zmieniam rozmiar okna to obszar roboczy ulega odswiezeniu i widac jak bitmapa jest rysowana (mryga na biało :P) i wlasnie chce zlikwidowac ten efekt... tak wiec ? :)

0

Noooo. W końcu jakieś konkrety. Powodem tego mrygania (prawdopodobnie) jest komunikat WM_ERASEBKGND. Nie będe tu opisywał do czego on służy - poszukaj sobie informacji w pomocy. Ja robie tak, że w procedurze okna przechwytuje WM_ERASEBKGND i nie puszczam go dalej do domyślnej procedury okienkowej (DefWindowProc). Oczywiście ten sposób sprawdzi się gdy twoja animacja zajmuje cały obszar okna/kontrolki. Jeśli jest to tylko jakiś fragment okna to musisz napisać własną obsługe komunikatu WM_ERASEBKGND, która nie będzie zamalowywać twojej animacji (tylko pozostały obszar okna).

Aha. Jeżeli tworzysz okna za pomocą funkcji Win API (ja używam VCL) to poczytaj o RegisterClass i WNDCLASS

PS. Tak w ogóle to topik powinien mieć chyba inny tytuł ;)

0

Ok. dzieki, poczytam i zobacze co mi z tego wyjdzie... :) nastepnym razem postaram sie lepiej precyzowac pytania...

PS. Jeszcze pewnie się w tym temacie odezwe bo zapewne czegoś znowu nie bede wiedzial :P

0

A moglibyscie dac mi jakies namiary na lekture dotyczaca podwojnego buforowania, tak oglnie na czym to polega ? z gory dzieki

aha i co do komunkatu WM_ERASEBKGND to nie dziala on zbyt dobrze... moze znacie jakies lepsze sposoby osiagniecie tego...

0

Chyba najlepszym namiarem będzie www.google.com ;)

aha i co do komunkatu WM_ERASEBKGND to nie dziala on zbyt dobrze... moze znacie jakies lepsze sposoby osiagniecie tego...

A co nie działa? Pamiętaj ważna jest też strategia rysowania.

0
jagi napisał(a)

Dobra widze ze musze dokladnie opisac o co chodzi :) To bedzie tak... napisalem "animacja" w cudzyslowiu,(...) chce zlikwidowac ten efekt... tak wiec ? :)

Uff :)

0x666 napisał(a)

Noooo. W końcu jakieś konkrety.(...)

Fakt, wreszcie :)
Tylko, że to nie musi być takie proste... bo tych okien, które się odrysowują może być kilka pod drodze :) Czyli mamy child na głównym oknie i on nie ściera tła, a za to rodzic sobie to robi... :> Zresztą to wszystko zależy jak utworzyliśmy okienka...
Dodam jeszcze, że style klasy okna dużo mieszają! Szczególnie upierdliwe przy odrysowywaniu to: CS_VREDRAW i CS_HREDRAW powodujące odrysowanie obszaru klienta (czyli erasebkgnd + ew. narysowanie kontrolki, itp.).

0

Czyli mamy child na głównym oknie i on nie ściera tła, a za to rodzic sobie to robi...

Teoretycznie style WS_CLIPCHILDREN i WS_CLIPSIBLINGS nie powinny dopuszczać do takich sytuacji - ale to teoria ;)

Szczególnie upierdliwe przy odrysowywaniu to: CS_VREDRAW i CS_HREDRAW

Czy ja wiem? Jeżeli zmiana rozmiaru okna zostanie odpowiednio obsłużona w WM_SIZE (np. przeliczenie współrzędnych itd.) plus główna procedura rysująca jest umieszczona w handlerze WM_PAINT to nie powinno być wiekszych problemów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1