|
dev.gamez.lv Latvian Game Developers Community
|
View previous topic :: View next topic |
Author |
Message |
elvman Indago Uzvarētājs
Joined: 09 Apr 2003 Posts: 1278 Location: Kuldiga
|
Posted: Sat Apr 01, 2006 1:49 pm Post subject: Logjika starp BeginScene un EndScene |
|
Shis nav tieshi DirectX specifisks jautaajums.
Taatad- paarmekleeju internetu un neatradu atbildi uz jautaajumu:
Vai var likt speeles logjiku (input apstraadi, AI utt.) starp BeginScene un EndScene (Direct3D) vai glBegin un glEnd (OpenGL)?
Sheit buus manas idejas (es zinu,ka taas iespeejams nav pareizas):
Iemesli kaadeelj tas nebuutu ieteicams:
-draiveris ir visu laiku taadaa kaa RenderState, kas vareetu pazeminaat programmas aatrdarbiibu
Iemesli kaadeelj tas buutu ieteicams:
-varbuut,kameer draiveris uzsaak sceenu (BeginScene vai glBegin) tiek dariiti apreekjini,liidz ar to tiek ieguuts laiks.
Nezinu kursh ir pareizais varinats (iespeejams abi ir nepareizi).
Parasti par sho jautaajumu neesmu domaajs-kaa sanaaca taa arii dariiju (dazhos projektos logjiku liku starp tiem,dazhos pirms tiem).
--EDIT--
Tiko ieshaavaas praataa->varbuut ir kaads iemesls logjiku likt peec EndScene vai glEnd? _________________ long time; /* know C */ |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sat Apr 01, 2006 1:58 pm Post subject: |
|
Nezinu kā ar ātdarbību, bet pašam loģiskāk un saprotamāk liekas, ka es spēles loģiku atdalu no grafikas renderēšanas. Tb vispirms visa loģika, sarēķinu visas vajadzīgās koordinātes/izmērus/u.tml stuffu. Un tikai tad saucu glBegin/glEnd, lai zīmētu vajadzīgās lietas. Tādā veidā rakstot kodu iespējams arī to viegli modficēt vairāku threadu darbībai, ka kamēr videokarte zīmē tekošo kadru, cpu jau rēķina nākamo. Ja būs viss vienā katlā sajaukts kopā, tas vairs nebūs tik viegli realizējams. |
|
Back to top |
|
|
elvman Indago Uzvarētājs
Joined: 09 Apr 2003 Posts: 1278 Location: Kuldiga
|
Posted: Sat Apr 01, 2006 2:04 pm Post subject: |
|
Nu jaa.Bet apskaties uz manu kodu,ja man naakas to atdaliit:
Code: |
switch(m_nGameState)
{
case GAME_MAINMENU: m_pMainMenu->Update(); break;
case GAME_GAME: m_pGame->Update(); break;
}
m_pRenderSystem->BeginScene();
m_pConsole->Draw();
switch(m_nGameState)
{
case GAME_MAINMENU:m_pMainMenu->Draw();break;
case GAME_GAME:m_pGame->Draw();break;
}
m_pRenderSystem->EndScene(); |
Man naakas divas reizes izmantot switch.
Bet vienkaarshaak vareetu:
Code: |
m_pRenderSystem->BeginScene();
m_pConsole->Draw();
switch(m_nGameState)
{
case GAME_MAINMENU:
m_pMainMenu->Update();
m_pMainMenu->Draw();
break;
case GAME_GAME:
m_pGame->Update();
m_pGame->Draw();
break;
}
m_pRenderSystem->EndScene();
|
_________________ long time; /* know C */ |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sat Apr 01, 2006 2:09 pm Post subject: |
|
Es tavā vietā šeit taisītu abstraktu klasi (aka interfeisu):
Code: |
class GameState {
public:
virtual void Update() = 0;
virtual void Draw() = 0;
// ...
};
class MainMenu : public GameState {
public:
void Update();
void Draw();
public:
// citi mainmeņu raksturīgie propetiji/metodes
}; // šis pats arī ar Game klasi
...
GameState* m_pState = NULL;
...
m_pState->Update();
m_pRenderSystem->BeginScene();
m_pConsole->Draw();
m_pState->Draw();
m_pRenderSystem->EndScene();
...
|
Tādējādi, kad spēles stāvoklis mainās (MainMenu<>Game), tad attiecīgi pamaini State objektu, lai tas norāda vai nu uz m_pMainMenu vai m_pGame.
btw: switch izmantošana šādiem mērķiem, lai izsauktu dažādu objektu vienādas metodes (tb veiktu līdzīgu darbību dažādos objektos) ir viens no rādītājiem, ka kodu iespējams vienkāršot, izmantojot polimorfismu - tb šādā veidā nomantot klases no kopēja vecāka. |
|
Back to top |
|
|
elvman Indago Uzvarētājs
Joined: 09 Apr 2003 Posts: 1278 Location: Kuldiga
|
Posted: Sat Apr 01, 2006 2:18 pm Post subject: |
|
Aha.Par shadu metodi nebiju iedomajies.Tas konkreti saisinas kodu.
P.S. goglee uzgaaju veel taadu metodi:
Code: |
RenderScene();
ProcessInput();
Update();
|
Tas ko piemineeju 1. postaa->updeitoshana peec Rendereeshanas _________________ long time; /* know C */ |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sat Apr 01, 2006 2:41 pm Post subject: |
|
Nav jau īsti atšķirības vai tu dari (Render Process Update):
vai
Darbību kārtība jau nemainās, tb aiz U vienmēr ir R un aiz R vienmēr ir P un aiz P ir vienmēr U. Atšķirās tikai sākums un beigas ;) |
|
Back to top |
|
|
elvman Indago Uzvarētājs
Joined: 09 Apr 2003 Posts: 1278 Location: Kuldiga
|
Posted: Sat Apr 01, 2006 2:47 pm Post subject: |
|
To es saprotu.bet jociigi sanaak->taatad pirmais freims tiek ziimeets bez updateoshanas (manaa gadiijumaa tas buutu tukshs ekraans,jo kamera netiek novietota kur vajag utt.),bet peedeejais freims tiek updateots par velti<-tas vairs netiek ziimeets.Stulba metode patiesiibaa. _________________ long time; /* know C */ |
|
Back to top |
|
|
gazz
Joined: 03 Jan 2004 Posts: 355 Location: Teika
|
Posted: Sat Apr 01, 2006 3:16 pm Post subject: |
|
njemot veeraa ka tev buus vismaz 60 kadri, par to iipashi nebuutu jaauztraucaas, bet aniiwei logisjkaak man shkiet PUR. Un par tiem interfeisiem - tieshi taa arii es taisu ka glabaajaas viens pointers ar patreizeejo GameState un shim tikai jaaizsauc interfeisa publiskaas metodes un viss notiek. Vienu lietu gan gribeetu piemetinaat - biju aizmirsis ka ja nenodefinee virtuaalo destruktoru interfeisam tad apakshklases destruktors netiek izskaukts ja meegjina delete uz interfeisa pointeri. Shaadi:
Code: |
class GameState {
public:
virtual ~GameState() {} /* bez shiis rindinjas apakshklases destruktors neizsauksies */
virtual void Render() = 0;
virtual void Update() = 0;
};
class MainMenu : public GameState {
~MainMenu() {}
void Render() {}
void Update() {}
};
...
GameState* gamestate = new MainMenu();
delete gamestate;
|
Biki nochakareejos kameer sapratu kur ir mans memory leaks. |
|
Back to top |
|
|
GiGa Indago Uzvarētājs
Joined: 25 Sep 2003 Posts: 887
|
Posted: Sun Apr 02, 2006 3:21 pm Post subject: |
|
Atgriežoties pie sākotnējā jautājuma, pāris random domas: man pareizākais RPU secības variants šķiet: P(UR) - tb, noprocesēt inputu un pēc tam renderēt un updeitot pēc iespējas paralēli, lai CPU nebūtu vienkārši jāgaida, kamēr GPU kaut ko norenderēs, bet izmantot to laiku kaut kādiem AI/fizikas aprēķiniem. Protams, tas sarežģī kodu, bet var iegūt ievērojamu ātrdarbības palielinājumu, itsevišķi, ja render kods smagi noslogo GPU, bet CPU paliek relatīvi neizmantots (piemēram, ja lielu daļu aprēķinu novirza uz vertex/fragment šeideriem, kā to mūsdienās arī vajadzētu darīt). Plus vēl, ņemot vērā, ka aizvien populārāki un pieejamāki kļūst vairāk procesoru PC, vispār veselīgi būtu sadalīt update un render procesus atsevišķos threados, ko par laimi laikam lielākā daļa fizikas bibliotēku dara jau pēc defaulta, un mums atliek tikai uztraukties par efektīvu AI un spēles loģikas implementāciju.
Teorētiski jau izklausās feini, bet praktiski to var nākties diezgan grūti izdarīt. Anyway, vienkārši gribēju pateikt, ka pilnībā nodalīt update no render procesiem vaŗbūt nav pārāk laba doma. |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sun Apr 02, 2006 3:36 pm Post subject: |
|
Ja kādu interesē precīzāki skaitļi, tad es kādu laiku atpakaļ biju testējis, cik izdevīgi ir atdalīt renderēšanu no fizikas aprēķiniem. Biju paņēmis vienkāršu scēnu, kur no gaisa krita bumbiņas un kubiki, fizikai izmantoju ODE. Fizikas aprēķini notika atsevišķā threadā. Šādi atdalot Update no Render, fps ieguvums sanāca aptuveni ~1.6 reizes (203 vs 322) uz divkodolu procesora (A64). Uz parasta vienkodola procesora zudumu nebija vērā ņemami - max 1 vai 2fps no ~100, vai pat bija arī ieguvums (no 2 threadiem) ~1.2 reizes uz vājākām videokartēm ar jaudīgāku cpu. (uz ļoti švakiem datoriem, kur fps ir labi ja 15, gan bija ievērojams kadru zudums ar 2 threadiem).
Pie tam, galveno PUR loopu es biju izveidojis tādā veidā, ka to vienkārši var pārslēgt no parasta PUR uz divthreadu darbību (izmanojot šeit sākumā manis minēto polimorfismu - ar divām mantotām klasēm). Tādā veidā programma startējoties var noteikt procesoru skaitu un attiecīgi izvēlēties vajadzīgo darbības kodu.
Mans secinājums no tā visa testa ir, ka lielākām spēlēm (nu ne jau kautkādām tur 2d arkādēm, protams) noteikti ir vērts pacensties uztaisīt atdalītu Render no Update, pēdējo ieliekot atsevišķā threadā. Un lai saglabātu savietojamību (tā to laikam nosaukt) ar vecākiem (t.i. švakākiem) cpu/videokartēm.
Sarežģīti un grūti tas nav, vienīgi ir jāuzumanās ar threadu sinhronizētu pieeju šārētiem datiem. Ja saprot, ko pats dara un ja iepriekš ir programmētas multi-threadētas aplikācijas, tad nevajadzētu būt problēmām. Protams, ja gribās ielikt arī citas resursapjomīgākas darbības (AI, skaņa, utml) atsevišķos threados, tad gan nāksies pasvīst ;)
Par pamatu biju ņēmis šo glfw exampļa kodu: particles.c (no sourceforge cvs). |
|
Back to top |
|
|
GiGa Indago Uzvarētājs
Joined: 25 Sep 2003 Posts: 887
|
Posted: Sun Apr 02, 2006 4:02 pm Post subject: |
|
Kā tu glabāji atmiņā savas bumbiņas/kubikus? Viena kopija, kura reizē tiek updeitota un renderēta, vai divas - viena updeitam, viena renderam? |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Sun Apr 02, 2006 4:08 pm Post subject: |
|
Objekti kā tādi glabājās ODĒ. Pēc Update veikšanas nolasīju visu objektu kordinātes/lenķus atsevišķos mainīgos, kurus izmanoju Renderēšanā. Šī arī ir tā vieta, kur abi threadi sinhronizēti drīkst piekļūt. Tb līdz ko Update pabeidza nolasīt šos mainīgos, Reners sāka renderēt ar tiem, bet Update sāka jau nākamo simulācijas iterāciju rēķināt. Līdz ko tas pabeidz, un gatavojās atkal nolasīt visas pozīcijas/lenķus, tas gaidīja, kamēr Renderis pabeigs zīmēt to iepriekšējo kadru (lai atbrīvotos tie mainīgie). |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|