Bu sayfadaki yazılar
Sayfanın metni
Sayfa 20
- Tamam güzeldir, nedir yani şimdi bu bahsettiklerimiz: ========================================================
Özetle şöyle basit bir şekil çizelim ascii'miz ile:
thread/task manager resource manager | |--> audio render timer -----> demo flow -- demo core engine -| (AV layer) | |--> video render memory manager
Her bi component aslında kendi başına bile kitap olabilecek kadar detaylı. Fakat demo durumunda bu detayları mümkün olduğunca atabiliriz. Ve işimize yarayan kadarı üstüne konuşup bi design çıkartabiliriz. Hangisinden anlatmaya başlayacağım ben de bilmiyom ama, şöyle basitçe bi timer'dan girelim bakalım nerelere gidiyor durum. Tabi bunu design ederken her zaman diğer component'ları gözümüzün önünde bulundurmalıyız ki, sonuçta çıkaracağımız design düzgün bir yapı olsun ve istediğimiz değişikliği parmak şıklatana kadar yapabilelim.
- Let the time flow: ====================
Evet timer. GetTickCount(), GetPerformanceCounter(), Gettime(), ... Bunlar boş şeyler. Yani önemli olan time'i nasıl aldığımız değil. Hiç de bir önemi yok. İki gün sonra function'ın adı belki de "GiveMeTheTimeMothaFucker()" olabilir. Dediğim gibi hiç bi önemi yok. Önemli olan burada bu time olayını nasıl olup da sisteme entegre edeceğiz. Bunun üstüne değineceğiz. Demonun akışı tamamen time'a bağlıdır. Belli bir zaman geldiğinde belli şeyler yapılması istenilir. Bunun design'ını yaparken bir başka istediğimiz husus, rahat debug edebilmek. Yani belki de istiyoruz ki bütün demo... Aslında yavaş çalışsın. Normal zamanın ne bileyim ben 9.3562 de birinde. Çünkü o zaman belki de görülmeyen bir bug'ı yakalayabiliriz.
Aynı yapı oyunlarda da çok sık kullanılır. Rahat debug edebilme, 'constant' fps sağlamak, gerektiğinde başka bi virtual timer ile değiştirmek, kafadan 40. saniyeden başlatabilmek... v.s. timeline gibi düşünün. nasıl ki ben 35.ci saniyeden film playlesin diyorsam demo'da da bunu diyebilmeliyim. ve her şey ona göre düzgün bir şekilde akmalı.
Tabi bütün bunların dışında en önemli sorun (ki bi çok kişinin dikkat etmediği mevzu...) Constant frame rate. Nasıl olur da sağlanır. ? Bıraktım demoyu bugün bi çok profesyonel oyun bile adam gibi sağlayabilmiş durumda değil bunu. Bi pixel ilerletirsin adamı/arabayı/ yaratığı... frame rate 75fps'den 35'e düşer. ... "u-uh.. No!.. Bad design".. Eee napacağız !? Hah çözüm bulduk!.. Bütün olayı 35 fps'ye setleyelim o zaman. O zaman düşmez. Yani bütün demo'ya bakalım en düşük kaç fps oluyor ona bakalım. Ona setleriz bütün akışı.. Yooo dostum yooo zaman cpu o 75fps yapabildiği yerde boş kalıyor mu olacak ?! Yok böyle bişii."unused system resource" exception fırlatılır suratına! Madem ki 2 cpu 1 gpu'muz var dibine kadar kullanıp. Mümkün olduğunca da constant frame rate nasıl sağlanır. bunu kasmak gerekmektedir. (bu arada design temelini 2 cpu 1 gpu muş gibi varsayıyorum. Şu an için sizde böyle bi sistem olmasa da bundan sonra böyle olacak bu iş.. Hatta yakında 4/8 cpu 2/4 gpu olması an meselesi. (sli cards, multiple cpu boards...etc.. Fiyatları her geçen gün düşüyor)
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 21
O zaman nasıl yaklaşmalıyız olaya. Oyunlarda çok sık kullanılan bir yöntemden bahsetmek istiyorum burda. Bu yöntemin bir dezavantajı var. Her şey totalde bir frame geriden takip ediyor. Yani şu an hesaplanan bir frame var fakat şu an çizilmekte (audio/video) olan frame aslında bi önceki frame. Basit bi delay özetle. Oyunda insanlar bunun kurtardığını söylüyor (50 fps hesabımız varsa 20 ms lik bi delayden bahsediyoruz).. Demo da hayli hayli kurtarır. Ama flexible ve constant time control çok önemli bi konu.
İlk vermemiz gereken karar demomuzun kaç fps olacağına karar vermek. "eee abicim varsın gitsin 1000 fps... süper işte baksana öküz gibi hızlı..." yav kime ne canım kardeşim 1000 fps ne... Aynı frame'i 1000 kere hesaplayıp basmanın kime ne faydası var""olur mu ya bak 760 fps idi... 1000 fps'ye çıkardım..." boş laflar bunlar. Basit bi filme bakalım sinemada gördüğümüz bir film 24 fps. televizyonda gördüğümüz sahneler 25 fps'dir. (50fps ama interlaced) bunun böyle yapılmasının sebebi insan gözünün onun ötesinde ki frame'leri aslında kaçırıyor olması. Yani arka arkaya akan 30 frame'e bi saniye de bakarsanız aslında göz biyolojik sebeplerden bu frame'lerin 6-7 tanesini kaçırır. Orda öyle bi resim gördüğünüzü bile bilmezsiniz. O yüzden bu fps'yi insanın nasıl algıladığına yakın bir şekilde seçmek kesinlikle makine açısından ve düzgün resource kullanımı açısından en güzel seçim olur. Oyunlarda bu biraz daha yüksek tutulur.. Örneğin 50-60fps oyun için yeterli bi fps'dir. Normal film fps'sinden biraz daha yüksek olmasının sebebi ortada bi user-interaction'in olmasından kaynaklanıyor. Yani tam frame'in başında bir hareket yaptığınız anda onun etkisini 40ms sonra ekranda görmek biraz delay'li olabiliyor (25fps = 40ms per frame) ama 20ms'lik bi delay açıkçası çok da belli olmuyor.. (yani 50 fps) ama başta da dediğimiz gibi demo olayında user interaction yok. Her şey kontrolümüz altında her türlü fake'e açığız. O yüzden birazcık daha düşük fps hedeflemek açıkçası bize koymaz.
Bi ikinci husus bu hedef fps yi seçerken, (hani demiştim ya diğer componentlara da bakmak lazım) gfx lib'imizi de göz önünde tutmak lazım. Ekranımızın tarama frekansı da çok önemli. Yani ekran update hızımızın monitor'un refresh rate'inin rational bi katı olması çok önemli örneğin 60hz tarayan bi monitorde kalkıp da 47fps lik bir rakamı oluşturmak biraz zor. Yani ekran update'imiz monitor ile sync değilse eğer, monitor ışın tabancası ekranın ortalarında bir yerde ise, biz ekranın üst kısmını update işlemine giriyor olabiliriz. Sonra update hızı monitor ışın tabancasını yakaladığı anda da monitor tabancasının alt kısmındaki yerleri update ediyor oluruz (tabi tabanca durmuyor o da devam ediyor yürümeye) o zaman monitor üst kısmı birinci frame'den tabancanın alt kısmını da ikinci frame'den göstermeye başlar.. Ve ortada böyle bi çizgi gibi bir şey görmeye başlarız. Bu da aynı önceki gibi.. "u-uh.. No ... Olmaz" gibi bir durum. Yani öyle bi ayarlamalıyız ki ya monitorun refresh hızında bir fps seçelim ya da onun bi katı (yani integer katı.. Ama inverse.. 1/2 1/3 1/4 gibi) diyelim açacağımız ekran 75 hz'lik o zaman 75 fps seçebiliriz. Bu da bize frame başına 13.33333ms gibi bişi bırakır. Baktık bu süre yeterli değil bizim için(ki aslında 75fps de fazla hani...) O zaman 37.5fps gibi bi fps seçebiliriz. 26.6666 ms ayırıyoruz şu an frame başına ve her iki taramada bir frame update geçiyoruz. 37.5 fps oluyor. Ama.. Yok kardeşim. Ben böyle ondalık istemiyorum diyorsak o zaman.. 60hz'lik bi ekranda 2 frame'de bir update ile 30fps'lik bir görüntü veya.. 80hz'lik bi ekranda 2 frame'de bir update ile 40 fps'lik bir görüntü (ki bu durumda 25ms kalıyor frame başına). Örnek olarak 40fps'yi hedef seçelim diyelim ki. Bu durumda bizim hedefimiz ekranımızı her 25ms'de bir update etmek olacak. Ve monitor refresh problemini halletmek için de 80hz'lik bir mode açıp her iki taramada bir update çekeceğiz. (bu demek değil ki monitor taramayacak... tabi ki o framebuffer'da ne varsa onu tarayacak. Biz sadece her 25ms'de bir o framebuffer'i update edeceğiz o kadar.)