[#1] [OS4/CGX] Jak zsynchronizować do ramki?
W jaki sposób pod OS4 oraz CGX zsynchronizować animację do ramki? WaitTOF() nie działa tak jak trzeba. Dzięki za odpowiedź.

[#2] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@Minniat, post #1

jakbys przeczytal poprzednie watki to znalazlbys odpowiedz w jednym z moich postow. slowa klucze to: AllocScreenBuffer (albo Create, nie pamietam) i ChangeScreenBuffer.

[#3] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@kiero, post #2

Dzięki za odpowiedź. Tak się składa, że zanim zadałem to pytanie korzystałem już z AllocScreenBuffer() oraz ChangeScreenBuffer() po Twojej wypowiedzi z "Pytania odnośnie grafiki w OS4". Miałem jednak z tym kłopoty.



Ostatnia modyfikacja: 17.03.2009 12:54:25
[#4] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@Minniat, post #3

Więc udało mi się w końcu dobrze rozpracować te funkcje. Używam tych poleceń (dla ekranu "screen" bez własnej bitmapy):

sb[0] = AllocScreenBuffer(screen, NULL, SB_SCREEN_BITMAP);
sb[1] = AllocScreenBuffer(screen, NULL, 0);

A następnie rysuję w bitmapę sb[toggle]->sb_BitMap i przełączam ekrany poprzez:

ChangeScreenBuffer(screen, sb[toggle]);
toggle ^= 1;

Mam tylko jeszcze jedną zagwostkę: mianowicie powinno się czekać na wiadomość, czy można blitować w bitmapę i czy można ją wyświetlić. Tylko, że oba polecenia AllocScreenBuffer() alokują aż dwie struktury DBufInfo.

struktura DBufInfo zawiera dwa pola:
- dbi_SafeMessage - wiadomość, że można blitować w bitmapę
- dbi_DispMessage - wiadomość, że można wyświetlić bitmapę

Trzeba zaalokować dwa porty i podpiąć je pod mn_ReplyPort obu wiadomości, a następnie czekać na te wiadomości aż dotrą do portu i wtedy podjąć odpowiednie czynności (blitować lub wyświetlać).

Jak to zaimplementować gdy dostępne są dwie struktury DBufInfo? Dziękuję za odpowiedź.

Tutaj podaję kod z RKRM, jeśli ktoś nie do końca wie o co mi chodzi (jest to kod przykładowy dla funkcji ChangeVPBitMap(), ale nie sugerujcie się tym, dotyczy on również ChangeScreenBuffer(). Dziękuję za odpowiedź.
The following fragment shows proper double buffering synchronization:

	int SafeToChange=TRUE, SafeToWrite=TRUE, CurBuffer=1;
	struct MsgPort *ports[2];    /* reply ports for DispMessage and SafeMessage 
*/
	struct BitMap *BmPtrs[2];
	struct DBufInfo *myDBI;

	... allocate bitmap pointers, DBufInfo, set up viewports, etc.

	myDBI->dbi_SafeMessage.mn_ReplyPort=ports[0];
	myDBI->dbi_DispMessage.mn_ReplyPort=ports[1];
	while (! done)
	{
	    if (! SafeToWrite)
		while(! GetMsg(ports[0])) Wait(1l<<(ports[0]->mp_SigBit));
	    SafeToWrite=TRUE;

	    ... render to bitmap # CurBuffer.

	    if (! SafeToChange)
		while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
	    SafeToChange=TRUE;
	    WaitBlit();         /* be sure rendering has finished */
	    ChangeVPBitMap(vp,BmPtrs[CurBuffer],myDBI);
	    SafeToChange=FALSE;
	    SafeToWrite=FALSE;
	    CurBuffer ^=1;	/* toggle current buffer */
	}
       if (! SafeToChange)	/* cleanup pending messages */
	    while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));
       if (! SafeToWrite)	/* cleanup */
	    while(! GetMsg(ports[0])) Wait(1l<<(ports[0]->mp_SigBit));


[#5] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@Minniat, post #4

Już wiem jak zrobić by wszystko działało poprawnie!

1. Więc najpierw alokujemy struktury ScreenBuffer:

sb[0] = AllocScreenBuffer(screen, NULL, SB_SCREEN_BITMAP);
sb[1] = AllocScreenBuffer(screen, NULL, SB_COPY_BITMAP);

2. Następnie tworzymy dwa porty:

ports[0] = CreateMsgPort();
ports[1] = CreateMsgPort();

3. I główna pętla animacji:

UBYTE toggle=0; // bieżący bufor, w który rysujemy

// Ustawiamy odpowiednie porty zwrotne
sb[toggle]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = ports[0];
sb[toggle]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = ports[1];

// Czekamy, czy możemy wyświetlić bufor (synchronizacja)
Wait(1l << (ports[1]->mp_SigBit));
ChangeScreenBuffer(screen, sb[toggle]);

toggle ^= 1; // zmieniamy aktualny bufor

// Czekamy, aż możemy rysować w bufor (synchronizacja)
Wait(1l << (ports[0]->mp_SigBit));
/* Tutaj dowolne operacje rysownicze */

4. I gotowe!

Wszystko już działa jak trzeba. Podwójne buforowanie przedstawione powyżej jest bardzo szybkie zarówno pod AGA jak i CGX/P96.

Pozdrawiam. :D

[#6] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@Minniat, post #5

Wrzuc te wartosci do zmiennych, szkoda za kazdym razem przesuwac i dobierarac sie do tego jak i tak maska jest stala.

1l << (ports[1]->mp_SigBit) , 1l << (ports[0]->mp_SigBit));

Co do Agi, WaitBlit() jest tam nie bez kozery.

[#7] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@AmiChris, post #6

Taka optymalizacja może być wprowadzona, ale operacja przesunięcia bitowego jest przecież bardzo szybka.
WaitBlit() owszem to dobry pomysł, gdy korzysta się z kości AGA.

--
Wdrożyłem się już całkiem dobrze w programowanie pod kartę graficzną. Różni się ono znacznie od programowania pod kości AGA. Przede wszystkim dane są w formacie chunky, a bitmapy są strukturami prywatnymi. W OS4 żeby dostać się do bitmapy trzeba wywołać funkcję:

lock = p96LockBitMap(struct BitMap *bm, struct RenderInfo *ri, LONG size);

struktura RenderInfo zawiera adres Memory pamięci gdzie znajdują się właściwe dane bitmapy w formacie chunky.

Teraz przez krótki czas możemy dowolnie modyfikować bitmapę. Blitowanie z maską jest realizowane poprzez skanowanie w pętli kolejnych pikseli i w miejscach gdzie jest obecny kolor 0 (tła) nie kopiujemy danych graficznych źródła, tylko zostawiamy tło.

Po skończeniu modyfikacji BitMapy trzeba odblokować bitmapę poprzez:

p96UnLockBitMap(struct BitMap *bm, LONG lock);

Zrobiłem testy i grafika może być blitowana w ten sposób z ogromną szybkością, np. odtwarzanie całego tła i rysowanie np. 300 obiektów w niskiej rozdzielczości jest realizowane w 50 ramkach na sekundę. Jest to duży potencjał, który można wykorzystać do stworzenia całkiem fajnych gier 2D lub nawet 3D.

[#8] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@Minniat, post #7

Czyżbyś miał zamiar napisać Dune3D ?

[#9] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@Arbuz, post #8

Obecnie piszę grę z Krzyśkiem Matysem, ale planuję też grę Dune 3 - z grafiką dwuwymiarową (nie 3D).

[#10] Re: [OS4/CGX] Jak zsynchronizować do ramki?

@Minniat, post #9

Tak sobie pomyślałem że masz taki zapas mocy na 3D to powstanie Dune 3D. A wersja na MOSa będzie Dune 3?

Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem