kategoria: C++
[#31] Re: [C] Silnik 3D

@arturB, post #30

Trochę strzał na oślep, ale czy ustawiasz dla swojego okna taga WA_RMBTrap? Skoro chcesz użyć prawego przycisku do własnych celów.
[#32] Re: [C] Silnik 3D

@arturB, post #30

Po prawdzie to musiałbyś pokazać jak otwierasz ekran i okno, wtedy można coś wywnioskować. Oprócz tropu, który zaproponował Krashan, to ja mogę napisać jak ja to robiłem; tylko nie pamiętam czy używałem myszki w produkcji; chociaż za kabana w tych sprawach to ja się nie uważam. W każdym razie ja to robiłem tak (jak są jakieś błędy to dajcie znać)

Otwierałem ekran (Screen) i na nim dawałem okno (na całym ekranie) typu backdrop
struct TagItem m_windowTags[] =
{
	{WA_CustomScreen, 0},
	{WA_Left, 0},
	{WA_Top, 0},
	{WA_InnerWidth, 0},
	{WA_InnerHeight, 0},
	{WA_Activate, TRUE},
	{WA_GimmeZeroZero, TRUE},
	{WA_Borderless, TRUE},
	{WA_Backdrop, TRUE},
	{WA_NoCareRefresh, TRUE},
	{WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS},
	{WA_Flags, WFLG_SUPER_BITMAP},
	{TAG_END, TAG_END},
};

// przed otwarciem okna ustawiałem tagi (g_nWinWidth = screen Width, g_nWinHeight = screen height)
// g_pScreen to adres ekranu
setWindowTag(WA_CustomScreen, (ULONG)g_pScreen);
setWindowTag(WA_InnerWidth, g_nWinWidth);
setWindowTag(WA_InnerHeight, g_nWinHeight);


I wtedy nie robiłem żadnych ScreenToFront ani innych cudów.
[#33] Re: [C] Silnik 3D

@asman, post #32

screen = OpenScreenTags(NULL,
SA_Title, "N.U.L.L.",
SA_DisplayID, displayID,
SA_Depth, 5,
SA_Width, xGained,
SA_Height, yGained,
SA_Type, CUSTOMSCREEN,
SA_ShowTitle, FALSE,
SA_Quiet, TRUE,
SA_Draggable, FALSE,
SA_Exclusive, FALSE,
SA_AutoScroll, FALSE,
SA_Colors, (ULONG)cols,
TAG_END);
}
}
}
win = OpenWindowTags(NULL,
WA_Left, 0,
WA_Top, 0,
WA_Width, xGained,
WA_Height, yGained,
WA_CustomScreen, (ULONG)screen,
WA_Backdrop, TRUE,
WA_Borderless, TRUE,
WA_DragBar, FALSE,
WA_Activate, TRUE,
WA_NoCareRefresh, TRUE,
WA_ReportMouse, TRUE, // mouse ON
WA_RMBTrap, TRUE,
WA_IDCMP, IDCMP_RAWKEY | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW,
TAG_END);
[#34] Re: [C] Silnik 3D

@arturB, post #33

Co moze zostalo niezauwazone, ale to dziala bez niczego , ale na trybach ecs i aga. Ale w rtg konieczne jest u mnie wymuszanie w petli ScreenToFront, inaczej co ramke gubie focus ?... chociaz tyczy to tylko prawej mychy bo reszta dziala bez uwag
[#35] Re: [C] Silnik 3D

@arturB, post #34

A możesz pokazać (nawet w pseudokodzie) jak wygląda główna pętla ?

Ewentualnie zejdź do jak najnmiejszego programu który ma ten feler i popatrz czy przypadkiem coś jest niewłaściwie robione, na przykłąd nie zbierasz wszystkich mouse eventów i dalsza część logiki przetwarza.

Bo tak na chłopski rozum w rtg coś jest szybciej wykonywane i Twój program tego nie ogarnia. A w ocs/aga akurat tak się szczęśliwie składa że jest dobrze.
1
[#36] Re: [C] Silnik 3D

@arturB, post #34

Ja mam pytania pomocnicze:

- Jakiego systemu RTG używasz?
- Czy system pod AGA i RTG masz identyczny? Czy na przykład pod RTG masz jakieś programy typu Commodity, które zczytują przyciski myszy jak np. MagicMenu?

Moim zdaniem albo to problem biblioteki RTG, albo jakiś zewnętrzny program wchodzi w interakcję z obsługą myszy. Bo załączony kod wygląda prawidłowo.

Ostatnia aktualizacja: 27.09.2025 14:40:07 przez Hexmage960
1
[#37] Re: [C] Silnik 3D

@Hexmage960, post #36

Z takich hardcorowych rozwiązań to może zablokować myszkę w window I obsługiwać ja z rejestrów lub przez gameport.device...
[#38] Re: [C] Silnik 3D

@mateusz_s, post #37

Z rejestrów to słabo, zważywszy że z tego co zrozumiałem jest to odpalane na OS4 i Morphos.
[#39] Re: [C] Silnik 3D

@asman, post #38

Dokladnie. Ma chodzic na wszystkim wiec tylko system. Z moich eksperymentow wynika ze RethinkDisplay(); ktory mam w aga/ecs po zmianie ekranow, nie wystepowal u mnie w trg. Po podstawieniu dziala myszka prawidlowo... ale fps drop tez jest. Wynika zatem ze screenToFront robi w rtg cos co m.in RethinkDisplay(); ... Trudno. Inaczej wytarguje te fpsy. RMB jest nieocenione. Na klasyku bez eksteremalnej dopalki to bedzie bolesne... chociaz zalozenie mam ze minimum 640x480 do grania. w 320x240 da sie odpalic ale w tych czasach pixele na ekranie np 27cali wygladaja jak awaria ekranu
[#40] Re: [C] Silnik 3D

@arturB, post #39

Dokladnie. Ma chodzic na wszystkim wiec tylko system. Z moich eksperymentow wynika ze RethinkDisplay(); ktory mam w aga/ecs po zmianie ekranow, nie wystepowal u mnie w trg. Po podstawieniu dziala myszka prawidlowo... ale fps drop tez jest. Wynika zatem ze screenToFront robi w rtg cos co m.in RethinkDisplay();

To ciekawe, bo RethinkDisplay() służy do odświeżania obrazu i wymagany jest tylko gdy wprowadzimy pewne zmiany do ekranów. Nie powienien wpływać na okienka.

I tak, ScreenToFront() wywołuje tę funkcję.

Notabene istnieje wiele sposobów by uzyskać podwójne buforowanie. Ja polecam bufory ekranu lub DBufInfo, z których korzystam z powodzeniem.

Metoda z podmianą RasInfo->BitMap i przebudową pochodzi z wersji 1.3 systemu.
[#41] Re: [C] Silnik 3D

@arturB, post #39

Są ludzie, którzy mają taką awarię na co dzień i to na 55 cala plus, bo zawsze można puścić na projektor. hehe
1
[#42] Re: [C] Silnik 3D

@arturB, post #39

Jesli by cie to zainteresowalo to moge ci podeslac program ktorego uzywam do testowania objektow 3D
do inter, ktory sam napisalem, mam tam obsluge myszki z dwoma klawiszami.
Program dziala pod RTG na 320x240 w 8 bitach.

Moglbys sprawdzic czy sa podobne objawy.
1
[#43] Re: [C] Silnik 3D

@Phibrizzo, post #42

Jak cos, to tu jest zrodlo glowne: otwarcie ekranu, okna itp.
link

A tu exec. Ma zaszyty jeden obiekt.
Rolka w myszce tez jest obslugiwana.

link

Dziala pod OS3.1 i MOSem.
3
[#44] Re: [C] Silnik 3D

@arturB, post #39

Może spróbuj mojego rozwiązania z którego korzystam pod RTG,
ono jest chyba najszybsze bo nie ma tu żadnych pośrednich kopiowań,
co narysujemy to wyświetlamy.

Korzystam z LockBitMapTags() + ChangeScreenBuffer() + WaitTOF()

Oto krok po kroku:

1. Korzystamy z systemowych buforów - używam ich równocześnie pod AGA jak i RTG nie ma tu problemu.

// DEKLARUJEMY - For double buffering.

static struct ScreenBuffer*     system__buffer[]                = { NULL, NULL };
static struct MsgPort*          system__display_port            = NULL;
static UBYTE                    system__safetochange;


2. Po utworzeniu SCREENA - Inicjujemy systemowe Buffory.
Pierwszy to będzie bitmapa utwrozonego juz screena, drugi bufor alokujemy sami.
Przy inicjalizowaniu drugiego bufora jest chyba jakis BUG - omijam to poprzez reczne utworzenie bitmapy.

system__buffer[0] = AllocScreenBuffer(system__screen, 0, SB_SCREEN_BITMAP);
 if (system__buffer[0]) system_console__write("[OK]");
 else
 {
     system_console__write("[FAILED]");
     system_console__write("\n\t\t### Critical error!");
     system_console__write("\n\t\t### Can't allocate screen buffers.");

     Delay(200);
     return 0;
 }

 system__buffer[1] = AllocScreenBuffer(system__screen, NULL, 0);
 if (system__buffer[1]) system_console__write(" [OK]");
 else
 {
     system_console__write(" [FAILED]");
     system_console__write("\n\t\t### Critical error!");
     system_console__write("\n\t\t### Can't allocate screen buffers.");

     Delay(200);
     return 0;
 }
        
 // Manual allocating second buffer because its not working (bug ?)...
 struct BitMap* tmp_bitmap = AllocBitMap(ENGINE_IO__SCREEN_WIDTH, ENGINE_IO__SCREEN_HEIGHT, 8, BMF_CLEAR | BMF_DISPLAYABLE, system__screen->RastPort.BitMap );
 if (tmp_bitmap == NULL)
 {
     system_console__write(" [FAILED]");
     system_console__write("\n\t\t### Critical error!");
     system_console__write("\n\t\t### Can't allocate screen buffers.");
     
     Delay(200);
     return 0;
 }

 FreeBitMap(system__buffer[1]->sb_BitMap);
 system__buffer[1]->sb_BitMap = tmp_bitmap;
 
 system__safetochange = 1;
 system__display_port = CreateMsgPort();
 system__buffer[0]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = system__display_port;
 system__buffer[1]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = system__display_port;

 // Attach buffer 1 to the screen.
 ChangeScreenBuffer(system__screen, system__buffer[1]);



3.
// Put screen to front.
 ScreenToFront(system__screen);




4. Teraz głowna pętla.

// przed pętlą:
LONG current_buffer = 0;   

// pętla
 while (ENGINE_io__global.is_loop)
{  
[...]

// Mój ENGINE rysuje co ma rysować do lokalizacji pod wskaźnikiem: unsigned char *ENGINE_io__global.output_buffer;
// W przypadku trybu RTG - nie alokuje tu żadnej pamięci - jest po prostu wskaźnik.
// Przed kolejną klatką pobieram do tego wskaźnika - adres bitmapy bufora będącego aktualnie "z tyłu":

APTR handle = LockBitMapTags(system__buffer[current_buffer]->sb_BitMap, LBMI_BASEADDRESS, (ULONG)&ENGINE_io__global.output_buffer, TAG_DONE);
UnLockBitMap(handle);

// ENGINE rysuje swoje do bitmapy systemowej bedącej "z tyłu", niewidocznej teraz..
ENGINE__run();

// Teraz podminiamy bufory:
 if (!system__safetochange)
{
   while (!GetMsg(system__display_port)) WaitPort(system__display_port);
   system__safetochange = TRUE;
}

if (ChangeScreenBuffer(system__screen, system__buffer[current_buffer])) 
{
   system__safetochange = FALSE;
}

current_buffer ^= 1;  
    

WaitTOF();

[...]
}


UWAGI:

1. Ważne - Zauważyłem, że jeżeli korzystamy z ChangeScreenBuffer() pod AGA to wraz z nim już jest juz WaitTOF() i nie trzeba go samemu dodawać.
ALE - ten sam ChangeScreenBuffer() w trybie RTG już nie uwzględnia WaitTOF() i trzeba samemu dopisać.

2. Z WaitTOF() pod AGA bedzie max 50 fps (chyba że NTSC to 60) , a z WaitTOF() pod RTG bedzie max 60 fps.

3. Jak chcesz zrezygnować z WaitTOF() żeby klatki leciały na ile fabryka dała - to wtedy może być tearing,
to możesz dodac wiecej tych buforów np. 3 zamiast dwóch.

4. To jest przykłąd dla RTG 8 bit, dlatego unsigned char *ENGINE_io__global.output_buffer;




Ostatnia aktualizacja: 28.09.2025 21:13:17 przez mateusz_s

Ostatnia aktualizacja: 28.09.2025 21:14:28 przez mateusz_s
2
[#45] Re: [C] Silnik 3D

@arturB, post #30

Cos sobie jeszcze przypomnialem.
Nie wiem jakiego systemu uzywasz ale te wczesniejsze z C= z 3.1 wlacznie (mozliwe ze w wyzyszch tez)
mialy takie male niedopatrzenie.
Polegalo ono na tym ze zmiana ekranu nie powodowala automatycznego przelacżenia odbioru informacji IDCMP.
Trzeba bylo kliknac lewym klawiszem myszki na takim ekranie.
Dopiero instalacja latki (np. MCP ja oferowala) naprawiala ten problem.

Moze tu lezy problem?

Ostatnia aktualizacja: 29.09.2025 10:58:13 przez Phibrizzo
[#46] Re: [C] Silnik 3D

@mateusz_s, post #44

Używając DBufInfo lub ScreenBuffer możemy być zawiadamiani kiedy możemy bezpiecznie rysować w bufor. Służy do tego wiadomość dbi_SafeMessage. Instalujesz swój port komunikacyjny podobnie jak ma to miejsce w przypadku dbi_DispMessage, czyli:

system__safetodraw = 1;
system__safe_port = CreateMsgPort();
system__buffer[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = system__safe_port;
system__buffer[1]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = system__safe_port;

W pętli analogicznie:

if (!system__safetodraw)
{
   while (!GetMsg(system__safe_port)) WaitPort(system__safe_port);
   system__safetodraw = TRUE;
}
/* Tutaj można bezpiecznie rysować */

To właśnie czekanie na dbi_DispMessage pełni rolę WaitTOF(), ponieważ ta wiadomość jest zwracana kiedy nasza klatka animacji została wyświetlona co najmniej raz.

I jeszcze mała uwaga:

if (ChangeScreenBuffer(system__screen, system__buffer[current_buffer])) 
{
   system__safetochange = FALSE;
}
current_buffer ^= 1;

Jeżeli zmiana buforów się nie powiodła (funkcja zwróci FALSE), powinieneś czekać aż się powiedzie. Można to zrobić w następujący sposób (z użyciem WaitTOF, by nie było Busy Wait):

while (!ChangeScreenBuffer(system__screen, system__buffer[current_buffer])) 
{
   WaitTOF();
}
system__safetodraw = FALSE;
system__safetochange = FALSE;

current_buffer ^= 1;

W przypadku ChangeVPBitMap() i DBufInfo nie trzeba tego robić, bo zmiana zawsze się powiedzie.

W tym schemacie WaitTOF() w głównej pętli animacji nie jest już potrzebny, bo tę rolę pełni czekanie na dbi_DispMessage.

Natomiast dbi_SafeMessage też jest ważny. Rysujemy w bufor dopiero gdy nie jest już wyświetlany. To czekanie jest krótkie.

Ostatnia aktualizacja: 29.09.2025 12:14:41 przez Hexmage960
2
[#47] Re: [C] Silnik 3D

@Hexmage960, post #46

Dodam jeszcze, bo nie mogę edytować, że jeżeli kolega chce by było "jak fabryka daje", może pominąć czekanie na dbi_DispMessage i tylko czekać na dbi_SafeMessage.

Fantastyczny przykład korzystania z ChangeScreenBuffer() i DBufInfo jest w Native Developer Kit 3.1 (NDK) na płycie Amiga Developer CD v1.1/v2.1. Znajduje się w katalogu NDK/NDK_3.1/Examples1/Intuition/DoubleBuffer.c.

Obraz tej płyty jest na Archive.org.

Ja lubię korzystać z DBufInfo asynchronicznie, tzn. czekać na wszystkie sygnały i obsługiwać je niezależnie.
1
[#48] Re: [C] Silnik 3D

@arturB, post #22

Jakoś nie zauważyłem wcześniej linku do filmu. Naprawdę zachęcająco to wygląda! Strategicznych gier kosmicznych w 3D nie kojarzę na Amigę. Jest tylko port takiej bardzo rozbudowanej, ale to na MorphOS (i AmigaOS4 pewnie też). Temat jest mi wyjątkowo bliski, bo od ponad 7 lat grzebię swojego kosmicznego pseudo-mini-RTSa na MorphOSa i końca nie widać. 😃
Trzymam kciuki za ukończenie projektu. Jeżeli możesz to wrzucaj filmy z postepu prac. Na pewno chętnie obejrzymy. OK
2
[#49] Re: [C] Silnik 3D

@Hexmage960, post #47

Przeprowadzilem sporo testow i kombinacji. Wyglada na to ze jedyny uzysk szybkosci wyswietlania jest w momencie gdzy silnik malo liczy. Ale w moim przypadku to sytuacje malo wazne. Tam gdzie sie poci nad transformacjami 3d i teksturowaniem i ostatecznie rysowaniem zysku nie ma zadnego zauwazalnego. Obecnie wiecej zamieszania to robi. Niz zakladalem. Wrocilem do podstawowego rozwiazania czyli WaitTOF. Dla mojej gry zadowalajace osiagi na klasyku w 640x480. A na Morphosie g4 to wogole nie ma znaczenia bo na pelnej rozdzielczosci pop...la. Mysle, ze w ten weekend zaprezentuje nowy material ze zmianami.
5
[#50] Re: [C] Silnik 3D

@MDW, post #48

link

Ostatnia aktualizacja: 05.10.2025 00:19:10 przez arturB
2
[#51] Re: [C] Silnik 3D

@arturB, post #49

Hej, czy na pewno korzystasz z buforów ekranu (lub DBufInfo) we właściwy sposób? Wystarczy, że w pętli głównej zrobisz rysowanie na wiadomości SafeMessage i po narysowaniu przełączasz. To wystarczy.

DispMessage nie trzeba instalować. (Ewentualnie pod AGA można użyć przerwania koprocesora wideo, ale to też nie jest konieczne).

Na Amidze z AGA DBufInfo pracuje bardzo dobrze. A rysuję bardzo wiele elementów. Działa płynnie niezależnie od obciążenia systemu.

Pytanie gdzie robisz obliczenia.

Oczywiście nie nalegam na zmianę rozwiązania. Chciałem tylko zapewnić, że bufory ekranu są OK.

Fajny efekt pracy widoczny na filmie. Mógłbyś wrzucić aktualny kod na GitHub.
1
[#52] Re: [C] Silnik 3D

@arturB, post #50

Ej fajne to.
1
[#53] Re: [C] Silnik 3D

@arturB, post #50

Kurcze- koparka mi opadła WOW ok, racjaOKOK
8
[#54] Re: [C] Silnik 3D

@BULI, post #53

Widać, że miłośnik Homeworldów.
1
[#55] Re: [C] Silnik 3D

@BULI, post #53

[youtube]https:https://youtu.be/WbRhSX9baNY[/youtube]

Demo wrzuciłem na itch.io Axion demo
Fajnie jakby ktoś spróbował to na jakimś 040. Nie testowałem poniżej 060/100mhz i rtg. Vampir i Warp też nie badane...
5
[#56] Re: [C] Silnik 3D

@arturB, post #55

Na A500 Pistorm z rpi4 śmiga w 1024x768 (20 fps przy ruchu statków)

Tylko musiałem zmienić w ikonce "Uruchom z:" na "Workbebnch" i zmieniłem stack z domyślnych 8192 na 30000, bo gra crashowała system.

W Pal uruchamia się w 320x256, ale wyciąga tylko 9fps

Ostatnia aktualizacja: 12.10.2025 09:58:04 przez TomcioPaluszek
3
[#57] Re: [C] Silnik 3D

@arturB, post #55

W natywnej rozdziałce, czyli 1680x1050 mam 59 fps



Edyta: znajomek odpalił w 640x480 na Blizzie1260/60, Mediator i jakiś Radeon - 9fps

Ostatnia aktualizacja: 12.10.2025 19:41:06 przez waldiamiga
3
[#58] Re: [C] Silnik 3D

@waldiamiga, post #57

O tak. Na Morphosach jest szybciej niz na pi. Myslalem ze bedzie wolniej ale jednak chodzi ultra plynnie. Nawet na fullhd. Na 60 fps jest blokada bo mi latalo na 140fps i za szybko bylo. Miejscami scina mimo wszystko do okolo 20-30
1
[#59] Re: [C] Silnik 3D

@arturB, post #58

Jutro mohę sprawdzić na A1200 z Warp 1260@100 otaz na A500 z PiStormem Classic z RPi 3A+@1.5GHz.

Jest szansa na optymalizacje, co by znajomek zagrał na więcej niż 9 fps na 060@60?
Planujesz wersję pod Warp3D? A natywne dla WarpUP, AmigaOS4x i MorphOS?
1
[#60] Re: [C] Silnik 3D

@arturB, post #58

To się w ogóle odpala na OCS/ECS ? Ile to ma kolorów ?

A przy przesuwaniu mapy/ruchu statków jest lock na 30fps ?
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