Tekrar merhaba Retrojen ailesi. Bu ne biçim başlık demeyin.
Retrojen'e Alcofribas'ın ikinci davetiyle, ikinci kez üye olmuş bulunmaktayım (sistem ilk üyeliğimi etkinsizlikten silmiş) :D
Madem bir fırsat daha verildi, bu defa iyi kullanayım ve şöyle etkili bir giriş yapayım dedim...
Ahem...
Bir süre önce YouTube'daki Bisqwit kanalında "bu iş bu kadar kolay mıymış?" dedirten şu videoyu izlemiştim.
https://www.youtube.com/watch?v=HQYsFshbkYw&t=188s (https://www.youtube.com/watch?v=HQYsFshbkYw&t=188s)
Arkadaş prototyping için Basic kullanıyordu. Ben de acaba bu kodu AMOS'a port etsem Amiga'da nasıl çalışır diye düşündüm ve satır satır aktarmaya başladım. Tabi ufak değişiklikler de yaptım. Bisqwit videosunun 2:51'nci saniyesinde VectorCrossProduct adlı bir formül kullandığını, bunu Vikipedi'den öğrendiğini ve tam olarak nasıl çalıştığını kendisinin de anlamadığını "karaBüyü gibi bir şey" diyerek belirtiyor. Formüle bakınca açıkçası ben de pek bir şey anlamadım, ancak bu formülle neyin amaçlandığını (sanırım) anladım ve aslında bir sürü çarpma ve bölme işlemine neden olan bu formülün aslında gerekli olmayabileceğini düşünerek, sadece tek bir çarpma ve bölmeden oluşan çok daha basit bir trigonometri formülüyle aynı işi hallettim. Bir de Inkey$ yerine çok daha hızlı çalışan Scancode kullandım.
Sonra basit bir harita oluşturup denemelere başladım. Baktım oldukça hızlı çalışıyor. Acaba buna texture mapping eklesem performans nasıl olur diye düşünmeye başladım. Daha önce texture mapping ile ilgili hiç araştırma yapmamıştım. Ama kafamda nasıl yapıldığına dair tahminler vardı. O tahminlerimi bir değerlendireyim bakayım ne performans alacağım dedim. Bir sürü deneme yanılmadan sonra o da oldu. Tabi performans pek düşük. Standart A1200'de saniyede 0.5 kare ancak çizebiliyordu. :)
060 A1200'de de saniyede 5 kare falan çizebiliyor sanırım. (tabi timer.device'ı açıp benchmark kodu yazmaya üşendim, göz kararı söylüyorum bunu :D)...
Sonra acaba bu kodu C'ye aktarsam ne kadar performans artışı olur diye düşünmeye başladım. Kullandığım komutlara göre AMOS her bir piksel için önce p2c sonra c2p çevrimi yapıyor olmalıydı. C'de bitleri (texture bitMap'inden, ekran bitMap'ine) doğrudan kopyalayarak bu çevrimleri aşabilirim ve hızlanır diye düşündüm. Hem C'ye geçince döngüler falan da daha hızlı çalışırdı herhalde. Bu sıralar C/C++ dillerinde kendimi geliştirmeye çalıştığım için güzel de bir antrenman olacaktı benim için.
Tabi bu bir sürü destek kodu yazmayı gerektirdi. AMOS'ta tek satır ile halledilebilen, DoubleBuffered ekran açmak ve bir ILBM brush dosyasını yüklemek için 600 küsur satır ilave kod yazmak gerekti. :(
Sonra dedim belki çok hızlı çalışırsa oyun falan yaparım bundan, iyisi mi harita koordinatlarını bir metin dosyasından parse ederek yükleyeyim dedim. 700 küsur satır da o tuttu iyi mi?
Yaptığım envai çeşit mantık ve söz dizimi hatasını gidermekle geçen bir hafta ardından sonunda çalıştırdım. Saniyede 10 kareye falan çıktık galiba. :)
Sonra bildiğim optimizasyonları uyguladım. Gereken fonksiyonları inline etmek, matematik işlemlerinde sadeleştirmeler, dinamik değişkenlerin DCache'de hit olması için MemoryPool kullanmak vs, vs... Derken saniyede 20 kareye falan çıkmış olabiliriz. Tabi bu 60Mhz 060 bir makinede, 4 renkli 100x100 bir ekranda, zemin ve tavan texture'ları olmadan.
https://www.youtube.com/watch?v=-jg18aASQFo (https://www.youtube.com/watch?v=-jg18aASQFo)
Benzer bir grafik motoru kullanan Gloom oyunu bu makinede, 64 renkli, tam ekranda (320x256), tavan ve zemin döşemeleri dahil 30 kare saniye verebiliyor.
Şöyle üstün körü baktığım birkaç makalede okuduğum kadarıyla, texture mapping için bazı aproksimasyonlar varmış. Düz Amiga'larda dişe dokunur kare saniyelere ulaşmak için sanırım onları öğrenmem ve uygulamam gerekiyor. Ha tabi geliştirilmiş Amiga'lar daki FPU'dan yararlanır hale getirmek de lazım. Tabi bunlar uzun, zorlu ve pek çok şey öğrenmemi gerektiren işler. Bakalım zamanla nereye varır bu macera?
Alcofribas'a teşekkürler ve her birinize tekrar selamlar arkadaşlar. Fikir ve yorumlarınızı bekliyorum.
Not: Kaynak kod paylaşmadım. Şimdi konunun gerçek uzmanı NightLord falan burada, görürse falan rezil olmayayım. :D Şaka şaka... isteyen olursa paylaşırım ama önce biraz derleyip toparlasam iyi olur. :)
Hoşgeldin Alper :)
Çok sağlam bir içerikle gelmişsin doğrusu, tebrikler. Bu arada geliştirme araçları olarak neler kullanıyorsun? Ben de adım adım Amiga sistemi kurmaya hazırlanıyorum da, aradan geçen 22 yıldan sonra. Ben 1995 yılında bıraktığımda AMOS Pro ve SAS/C kullanıyordum...
Alıntı yapılan: witchdoktor - 01 Haziran 2017, 16:57:35
Hoşgeldin Alper :)
Çok sağlam bir içerikle gelmişsin doğrusu, tebrikler. Bu arada geliştirme araçları olarak neler kullanıyorsun? Ben de adım adım Amiga sistemi kurmaya hazırlanıyorum da, aradan geçen 22 yıldan sonra. Ben 1995 yılında bıraktığımda AMOS Pro ve SAS/C kullanıyordum...
Teşekkürler witchdoktor. Hoşbulduk. :)
Şimdilik Windows üzerinde AmigaOS 3.9 kurulu WinUAE ile geliştiriyorum.
Amos kodunu AmosPro ile yazdım. C kodu için Windows'ta (kendi hazırladığım language-amigaos-c (https://github.com/alpyre/language-amigaos-c) paketi yüklenmiş) Atom (https://atom.io/) ile yazıyorum. Sonra WinUAE geçip SAS/C ile derliyorum. Tabi Amiga tarafında CubicIDE (https://www.softwareandcircuits.com/division/amiga/products/cubic/) de kurulu. Aslında projelere onunla başlıyorum. Yeni proje oluşturunca SAS/C ve AmigaOS uyumlu bir "Hello World" ve otomatik makefile hazırlıyor. Ardından Windows tarafındaki Atom'a geçip onunla devam ediyorum tabi.
Aslında idealim Linux üzerinde Atom ve m68k-gcc ile derlemek. Ama 64bit Linux'larda JIT destekli bir Amiga emülatörü henüz yok. 32bit Linux'u da makinaya ana işletim sistemi olarak kurmak istemiyorum (Chrome falan çalışmıyor).
Şimdilik böyle idare ediyorum. Linux'a düzgün bir emülatör gelirse değişiklik yapabilirim.
Alıntı yapılan: Alpyre - 01 Haziran 2017, 14:32:14
Tekrar merhaba Retrojen ailesi. Bu ne biçim başlık demeyin.
Retrojen'e Alcofribas'ın ikinci davetiyle, ikinci kez üye olmuş bulunmaktayım (sistem ilk üyeliğimi etkinsizlikten silmiş) :D
evet ilk açıldığımızda bayağı sert bir politika izliyorduk üyelikler konusunda. sonra gevşedik. :)
tekrar hoşgeldin.
Alıntı Yap
Sonra basit bir harita oluşturup denemelere başladım. Baktım oldukça hızlı çalışıyor.
amos'u çok severim. Lakin amiga karmaşık bir makine. Bir sürü custom chip. Hepsini öğrenmek gerekiyor çok basit bir kod için bile. Amos bugün benim maintain ettiğim basin gibi, all-in-one bir araç. Kodlamayı eğlenceye çeviren düzgün bir editörü var vs. En son gui extension ile workbench uygulamaları yazıyordum, doğrusu amigadan windows'a geçişimi acaip hızlandırmıştı.
Amosta texture'suz haliyle kaç fps çiziyordu acaba?
Alıntı YapBu sıralar C/C++ dillerinde kendimi geliştirmeye çalıştığım için güzel de bir antrenman olacaktı benim için.
Hmm ne tür bir dil? Var olan bir dilin dialekti mi yoksa brainfuck gibi yeni bir tür mü :D bir de neden?
Alıntı YapDerken saniyede 20 kareye falan çıkmış olabiliriz. Tabi bu 60Mhz 060 bir makinede, 4 renkli 100x100 bir ekranda, zemin ve tavan texture'ları olmadan.
bu işlemlerin tamamını cpu ile yaptırdığını tahmin ediyorum. 20 fps hiç de az değil. Amiga'dan bahsediyoruz, 60mhz 060 bile olsa. Oyun olsa mis gibi oynanır :D Bence sen 680x0'in sınırına dayanmışsın. C kod optimizasyonu en azından elindeki kod ile 1-2 kareden fazla eklemeyecektir. Artık amiga kodlamaya geçmen gerekiyor büyük ihtimal. lakin işi bozan amiganın planar buffer'ı oluyor en başta. Al rengi, böl kanallara, ayrı ayrı yaz falan... Ekranı boyamak için sprite'ları vb. kullanmak mümkün olabilir mi acaba? İşi paula yapsın. Amigada time critical kod yazmamış biri olarak bunu önermek ne kadar sağlıklı bilmiyorum :D
Alıntı YapHa tabi geliştirilmiş Amiga'lar daki FPU'dan yararlanır hale getirmek de lazım.
FPU mutllaka çok yardım edecektir ama amigada FPU küçük bir zümrenin deneyimleyebildiği bir lüks :D fpu gelene kadar bazı fonksiyonları asm olarak kodlasan/unroll etsen? 3-5 kare de ordan gelecektir bence.
Alıntı YapKaynak kod paylaşmadım. Şimdi konunun gerçek uzmanı NightLord falan burada, görürse falan rezil olmayayım. :D Şaka şaka... isteyen olursa paylaşırım ama önce biraz derleyip toparlasam iyi olur. :)
Hahahah, bence kod paylaşırsan wisdom, mert, skate, ve nightlord'dan babalar gibi öneriler gelebilir.
Alıntı YapBenzer bir grafik motoru kullanan Gloom oyunu bu makinede
Gloom ile karşılaştırdığın için eklemek istiyorum, stok a500'de çalışan iki oyun vardı:
https://www.youtube.com/watch?v=Q_rFTtQ9Kuk (https://www.youtube.com/watch?v=Q_rFTtQ9Kuk)
7mhz için çok hızlı, kısmen küçük texture'lar var falan. Kimbilir ne tür bir trick var burda, belki gerçekten 3D bile değildir. :)
Son dönem citadeli oynuyordum (ya da oynamaya çalışıyordum--bende adspeed (http://amiga.resource.cx/exp/adspeed) var--):
düz a500 1mb'da 4fps falan çiziyor: https://www.youtube.com/watch?v=g33XP9hXbdI (https://www.youtube.com/watch?v=g33XP9hXbdI)
benim makinede demekki 8fps çiziyormuş, o sırada pc de vardı wolfenstein falan oynuyorduk, citadel hakkındaki görüşlerim çok karanlık...
İşte aslanlar gibi bir girizgah :) Ellerine beynine sağlık Alpyre...
Ama 2 fps'den 20 fps'ye giden yolda hissettiklerin tek kelime ile "harika" değil mi? 10x bir hız farkı.
Amiga hakkında hiç tecrübem olmadığı için benim yapabileceğim yorumlar kısıtlı olacak. Bunları ihtimalen düşünmüşsündür ama bu tür motorlar için aklıma gelenler standart olarak:
- loop'ların içinden çıkabilecek şeyleri arayıp bir üste çıkarmak. Yani per-frame olması gereken birşeyin per scanline (veya per pixel) yeniden hesaplanmaması, immutable birşeylerin per frame olmaması vs.
- faydalanabilecek simetri aramak. Mesela texture'ları y yönünde simetrik yapsan bir texture lookup ile iki piksel basabilir misin? Veya haritayı dizayn ederken yapabileceğin, kodu hızlandıran hileler var mı? Bazı corner-case'ler level dizayn ile elimine edilebiliyor mu?
- mesela duvarlar hep birbirine dik olursa (yani hep kuzey güney veya doğu batı yönünde olursa) hızlanır mısın?
- matematiği mümkün olduğunca fixed-point integer tutmak da Amiga'da daha iyi sonuç verebilir.
Bu önerilerin bazıları yine modern yazılım mühendisliği çevrelerde insanların yüreğine indirebilecek öneriler :) ama daha bugün bir John Romero videosu izledim. Id'in ilk yıllarından takip ettikleri kurallardan biri:
"Kodu sadece şu anda yaptığınız oyun için yazın, bir sonraki oyuna yeni kod yazarsınız"
heheheh ama motor lisanslayan ilk firma da id olduğuna göre varın siz karar verin John abi'yi ne kadar dikkate almalıyız :)
Tekrar tekrar eline sağlık
Harika bir çalışma, elinize sağlık. Coder olmadığımdan bir yardımım dokunamayacak, ancak A500 ve A1200 ile geçirdiğim 7 yıldan sonra, Amiga'da işin içine texture'lar girdiğinde 3D performansının daima dibe indiğini gördüğümden, başardığınız işi tebrik etmeden geçmemek istedim. Özellikle son optimize hali Amiga için çok yumuşak çalışıyor.
Alıntı yapılan: Ref - 02 Haziran 2017, 10:58:29
Gloom ile karşılaştırdığın için eklemek istiyorum, stok a500'de çalışan iki oyun vardı...
Belirttiğin oyunları hiç görmemiştim, özellikle Behind The Iron Gate müthişmiş. Her ne kadar birkaç doku haricinde vektörel ağırlıklı olsa da A500'de çalıştığına inanmakta zorlandım. Benim bildiğim A500'de çalışan Death Mask vardı, A500'üm ile ayrılmadan önceki son günlerimde çıkmıştı ve fps sevmediğim halde ne kadar yapabildiklerini merak ettiğimden almıştım. A500'e optimize edebilmek için olabilecek hemen her hileyi kullanmışlar oyuna gerçekten 3D demek mümkün mü bilemiyorum, kesintisiz hareket bile yok, her şey 4 yönlü:
https://www.youtube.com/watch?v=842i-OqL18U (https://www.youtube.com/watch?v=842i-OqL18U)
Alıntı yapılan: fullgrim - 03 Haziran 2017, 01:25:55
Benim bildiğim A500'de çalışan Death Mask vardı
death mask'ı biliyordum, dungeon master'ın sürekli aksiyon şeklinde geçmesi hali.
@RefHoşbulduk.
Alıntı yapılan: Ref - 02 Haziran 2017, 10:58:29
Alıntı yapılan: Alpyre - 01 Haziran 2017, 14:32:14Bu sıralar C/C++ dillerinde kendimi geliştirmeye çalıştığım için güzel de bir antrenman olacaktı benim için.
Hmm ne tür bir dil? Var olan bir dilin dialekti mi yoksa brainfuck gibi yeni bir tür mü :D bir de neden?
Yok. Bildiğin C ve C++ dilleri. Nedenine gelince de... Bilmem ki. Yıllardır hep heves edip fırsat bulamadığım bir şeydi C öğrenip Amiga programı yazmak. :)
Alıntı yapılan: Ref - 02 Haziran 2017, 10:58:29
Alıntı yapılan: Alpyre - 01 Haziran 2017, 14:32:14Derken saniyede 20 kareye falan çıkmış olabiliriz. Tabi bu 60Mhz 060 bir makinede, 4 renkli 100x100 bir ekranda, zemin ve tavan texture'ları olmadan.
bu işlemlerin tamamını cpu ile yaptırdığını tahmin ediyorum. 20 fps hiç de az değil. Amiga'dan bahsediyoruz, 60mhz 060 bile olsa. Oyun olsa mis gibi oynanır :D Bence sen 680x0'in sınırına dayanmışsın. C kod optimizasyonu en azından elindeki kod ile 1-2 kareden fazla eklemeyecektir. Artık amiga kodlamaya geçmen gerekiyor büyük ihtimal. lakin işi bozan amiganın planar buffer'ı oluyor en başta. Al rengi, böl kanallara, ayrı ayrı yaz falan... Ekranı boyamak için sprite'ları vb. kullanmak mümkün olabilir mi acaba? İşi paula yapsın. Amigada time critical kod yazmamış biri olarak bunu önermek ne kadar sağlıklı bilmiyorum :D
Yok yapabileceğim pek çok optimizasyon daha var gibi görünüyor. Planar ekran hiç problem değil. Çünkü texture'ım da planar. Chunky2Planar çevrimi hiç yapmıyorum. Kordinatlar hesaplandıktan sonra, her plane için texture'ın ilgili konumunda bit set mi diye bakıp, set ise ekran bitmapinde de o biti set yapıyorum. Tabi bu bütün yükü CPU'ya bindiriyor. Blitter'ı sadece ekranı hızlı şekilde temizlemek için kullanıyorum şimdilik.
Alıntı yapılan: Ref - 02 Haziran 2017, 10:58:29
Alıntı yapılan: Alpyre - 01 Haziran 2017, 14:32:14Ha tabi geliştirilmiş Amiga'lar daki FPU'dan yararlanır hale getirmek de lazım.
FPU mutllaka çok yardım edecektir ama amigada FPU küçük bir zümrenin deneyimleyebildiği bir lüks :D fpu gelene kadar bazı fonksiyonları asm olarak kodlasan/unroll etsen? 3-5 kare de ordan gelecektir bence.
asm bilgim sıfır. O yüzden şimdilik mecburen C'den devam... :)
Alıntı yapılan: Ref - 02 Haziran 2017, 10:58:29
Alıntı yapılan: Alpyre - 01 Haziran 2017, 14:32:14
Sonra basit bir harita oluşturup denemelere başladım. Baktım oldukça hızlı çalışıyor.
amos'u çok severim. Lakin amiga karmaşık bir makine. Bir sürü custom chip. Hepsini öğrenmek gerekiyor çok basit bir kod için bile. Amos bugün benim maintain ettiğim basin gibi, all-in-one bir araç. Kodlamayı eğlenceye çeviren düzgün bir editörü var vs. En son gui extension ile workbench uygulamaları yazıyordum, doğrusu amigadan windows'a geçişimi acaip hızlandırmıştı.
Amosta texture'suz haliyle kaç fps çiziyordu acaba?
Aynen dediğin gibi. Amos ergenliğimin en eğlenceli yanıydı. Hala da dönüp dolaşıp ona dönüyorum baksana. :D
Amos'ta texture'sız hali stok A1200'de 6-9 FPS arasında gidip geliyor. 060'ta ise 25-30 arası. (Bu defa göz kararı değil, koda FPS sayacı ekledim. Hatta kodu da ekledim. Amiga'sı olanlar deneyebilir. Amos'u olmayanlar için derlenmiş executable da attım.)
Alıntı yapılan: Ref - 02 Haziran 2017, 10:58:29
Alıntı yapılan: Alpyre - 01 Haziran 2017, 14:32:14Benzer bir grafik motoru kullanan Gloom oyunu bu makinede
Gloom ile karşılaştırdığın için eklemek istiyorum, stok a500'de çalışan iki oyun vardı:
https://www.youtube.com/watch?v=Q_rFTtQ9Kuk (https://www.youtube.com/watch?v=Q_rFTtQ9Kuk)
7mhz için çok hızlı, kısmen küçük texture'lar var falan. Kimbilir ne tür bir trick var burda, belki gerçekten 3D bile değildir. :)
3D değil zaten. 2.5D diyorlar buna... Bu oyunu hatırlıyorum. Biraz inceleyeyim bakayım kopya çekebilirim belki bazı özelliklerinden. Çok teşekkürler.
@nightlord
Alıntı yapılan: nightlord - 02 Haziran 2017, 11:35:27
İşte aslanlar gibi bir girizgah :) Ellerine beynine sağlık Alpyre...
Ama 2 fps'den 20 fps'ye giden yolda hissettiklerin tek kelime ile "harika" değil mi? 10x bir hız farkı.
Kesinlikle harika. Tabi 1 saatte yazdığım kodu bazen 1 günde debug ettiğim için, en büyük keyif çalıştığını gördüğüm an oluyor. Ahaha :D
Alıntı yapılan: nightlord - 02 Haziran 2017, 11:35:27Amiga hakkında hiç tecrübem olmadığı için benim yapabileceğim yorumlar kısıtlı olacak. Bunları ihtimalen düşünmüşsündür ama bu tür motorlar için aklıma gelenler standart olarak:
- loop'ların içinden çıkabilecek şeyleri arayıp bir üste çıkarmak. Yani per-frame olması gereken birşeyin per scanline (veya per pixel) yeniden hesaplanmaması, immutable birşeylerin per frame olmaması vs.
Optimize ederken ilk yaptığım bu oldu zaten. Hissedilir kazanç bundan oldu sanırım.
Alıntı yapılan: nightlord - 02 Haziran 2017, 11:35:27
- faydalanabilecek simetri aramak. Mesela texture'ları y yönünde simetrik yapsan bir texture lookup ile iki piksel basabilir misin?
İşte bu satır "mind blow" yaptı be abi... Texture'ım simetrik olursa ufuk çizgisinin üstü ve altı (bu uygulamada) tamamen simetrik olur. Hatta duvarların sadece üst kısmını çizip, alt kısmını blitter çipiyle kopyalayabilirim. Hatta çizim öncesi ufuk çizgisinin altında kalan kısmı temizlemem bile gerekmez bu durumda. Ya bu gerçekten çok aşırı hızlandırabilir ya... Süper oldu bu! Çok çok çok teşekkürler...
Tabi oyun yapacaksam bu çok tek düze bir görsele neden olabilir. Bazı ufak duvarları da eski yöntemle asimetrik çizersem ikisinin karışımı ne yaptığımı gizleyebilir.
Alıntı yapılan: nightlord - 02 Haziran 2017, 11:35:27
- mesela duvarlar hep birbirine dik olursa (yani hep kuzey güney veya doğu batı yönünde olursa) hızlanır mısın?
Bu sadece oyuncunun haritanın hangi sektöründe olduğunu hesaplarken ve duvarların içinden geçememesini sağlarken kazanç sağlayacak bir şey gibi. Henüz oralara hiç girmedim :)
Alıntı yapılan: nightlord - 02 Haziran 2017, 11:35:27
Bu önerilerin bazıları yine modern yazılım mühendisliği çevrelerde insanların yüreğine indirebilecek öneriler :) ama daha bugün bir John Romero videosu izledim. Id'in ilk yıllarından takip ettikleri kurallardan biri:
"Kodu sadece şu anda yaptığınız oyun için yazın, bir sonraki oyuna yeni kod yazarsınız"
heheheh ama motor lisanslayan ilk firma da id olduğuna göre varın siz karar verin John abi'yi ne kadar dikkate almalıyız :)
Tekrar tekrar eline sağlık
Sağol Nightlord. Bu yazdıkların gerçekten enerji ve yeni fikirler verdi. Hatta ilgisi yok ama, düşünürken serbest çağrışımla sanırım Gloom oyununda uzaktaki duvarların nasıl daha karanlık çizildiğini de buldum.
Şimdi işten çıkıp eve gidip klavyeye gömülmek için can atıyorum. Çok çok sağol.
koda ben de baktım biraz önce. Amos'da 7 fps çiziyor gibi görünüyor. Ortadaki haritayı çizen kodu kapatınca 9-10fps oldu.
sürekli olarak float hesaplar var, dediğin gibi hız, precision sebebiyle kaybediliyor. Integer math, sin ve cos'u tabloya çekmek, iç içe küçük FOR..next'leri unroll etmek acaba ne kadar kazandırır (0.5 kare falan?). Belki bir ara denerim :D
ayrıca blitter (http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0128.html) ile çizgi çizdirilebiliyor. amosda pload ile derlenmiş asm kullanılabiliyor. bu kod çok hızlı çalışabilir büyük olasılıkla.
Ahah, bu kod 1991'de olacaktı ki elimde :) kimbilir daha neler kaçırdım...
Alpyre hoşgeldin! Bu harika başlığı fazla meşgul etmemek adına, eğer kabul ediyorsan hemen siparişlerimi verip kaçıyorum. Bu bağlamda ileride senden görmeyi arzu ettiğim örnek başlıklar:
1-) Amiga'da Müzik üretimi (Temel müzik bilgisi de içeren HowTo tarzı bir manual) (Amiga dedim ama PC de olabilir fakat çok hardcore ve crack gerektiren programlarla olmasın, düsturumuz KISS metodu biliyorsun)
2-) Yıldızı barışmayanlar veya kullanım alışkanlığı edinemeyenler için Linux
Ağanın eli tutulmaz :)
Tamam Alcofribas. Siparişleri aldım. :)
(Gerçi bu kadar üstadın arasında Linux hakkında konuşmak ne kadar bana düşer onu bilemedim ama... neyse... seni kıramam.)
Şimdi şöyle özet bir bayram güncellemesi yapayım şu başlığa. :)
Ref'in ve nightlord'un önerilerini değerlendirdim ve elimden geldiğince uygulamaya çalıştım.
İlk önce PPaint'te tuğla duvar kaplamamı ufuk çizgisinin üstü ve altı simetrik olacak şekle getirdim.
(https://i.hizliresim.com/ok3AyX.gif)
Programı ekranın sadece ufuk çizgisinin üstündeki kısmını çizdirdikten sonra, alt kısma ters çevirerek BlitCopy yapacak şekilde değiştirdim. FPS bir anda yaklaşık iki katına çıktı.
Tabi hepsinden önce çok önemli bir eksiğim vardı. Oyuncuya yakın olan duvarların ardında kalan duvarların sadece görünen kısımlarının çizilmesi gerekiyordu (Amos kodumda da, C kodumda da bu yoktu, sadece oyuncunun durduğu yere göre duvarların çizim önceliği değişiyordu).
Öğrendiğim kadarıyla bu üç farklı şekilde hallediliyor.
1) John Carmack'ın Wolfenstein 3D'de kullandığı ray casting...
2) veya (IDTech1'de) kullandığı BSP ağacı...
3) veya Ken Silverman'ın (Build Engine'de) kullandığı "portal" yöntemi...
Ray Casting kodumuzun hali hazırdaki haline zaten uygun değil. Komple yeniden tasarlamayı gerektirir.
BSP, harita formatımı çok değiştireceği için üşendim fakat bazı fikirleri aldım.
Portal yöntemi aklıma yattı (bisqwit de bunu uyguluyor videosunda bu arada).
BSP ile Portal yöntemlerinin sadeleştirilmiş bir karışımını uygulamaya karar verdim. Harita verisinde çok ufak değişiklik ile duvarların arkasında kalan duvarların sadece görünen kısmı çiziliyor artık. Ayrıca sadece bir iki tam sayı karşılaştırma ile de portallar görüş alanında değilse hiç hesaplama yapmadan tamamen atlanıyor. Aşağıdaki animasyonda bakış açısına göre hesaplanan duvarlar görüntüleniyor:
(https://i.hizliresim.com/ER8zZg.gif)
Not: Bu arada IDTech1'deki gibi duvarların çizimi görüş alanını doldurduğunda (yani ekran yatay çözünürlüğü kadar piksel yazıldığında) tüm döngülerden erken break yapmak da aklımda. Bir ara onu da ekleyeceğim.
Vertex struct'larında ekran kordinatları için iki buffer açtım. Bir vertex en az iki duvar tarafından ve bazen de portallar için kullanılabiliyordu. Aynı vertex için iki üç defa transform işlemleri yapılmamalıydı. Artık ilk yapıldığında sonucu bellekte tutuyor, ikinci kez ihtiyacı olduğunda bellekten çağırıyordu.
Sonra Sin ve Cos değerleri için bir look-up tablosu hazırladım. Zaten oyuncuyu 5'er derece döndürüyordum. 72 değerlik bir tablo can yakmazdı. Sonra baktım ki bu değerlerin çoğu birbiriyle zaten aynı (işareti ve sırası değişiyor sadece). Look-up fonksiyonunu geliştirdim, tablo 18 değere düşüverdi. :)
Orada burada bir kaç optimizasyon daha yaptıktan sonra bahsettiğiniz şu Floating Point kullanmama konusu. Bunun olabileceğini hiç düşünmemiştim... fakat bir aralar StackOverflow.com'da bir kullanıcının "asla Float kullanma, değişkenlerini bir katsayı ile çarp, tüm işlemlerini yap, sonra o katsayıya böl" gibi bir önerisini okuduğum aklıma geldi.
Okuduğumda 'yav hiç olur mu öyle şey be...' demiştim. Çünkü işlemler sırasında değişkenler birbiriyle çarpılırsa katsayının karesi ortaya çıkardı... ama aklıma gelmişken denemeliydim.
Evet değişkenlerim bazen birbirine çarpılıyor, bazen de bölünüyordu. Fakat işlem sıralarıyla biraz oynayarak doğru sonuçları elde etmeyi başardım ve koddan tüm FLOAT değişkenleri temizledim. Her şey INT artık.
Katsayı olarak da önce 100 seçtim. Sıfırdan sonra iki basamak precision yeterdi. Sonra kendime dedim ki, neden 100? (Sonuçta bilgisayarlar ondalık sayı kullanmıyor). 128 olsun, çarpma bölme yerine de bitshift kullan. Daha sonra 64'te karar kıldım. 6 bitlik precision yeterli görünüyordu.
Vertex hesaplamaları yeterince yaklaşık sonuç veriyor, duvarlar yerli yerinde ancak texture mapping o kadar iyi olmadı. Aşağıdaki gibi bir glitch ortaya çıktı (sanırım buna benzer glitchleri PlayStation 1 oyunlarında görmüştüm... onlar da mı Float kullanmıyordu acaba? Bilmiyorum).
Duvara yaklaşınca ortaya çıkan üçgen üçgen görüntüleri sineye çekebilirim. Hatta oyuncunun duvarlara fazla yaklaşmasını engelleyerek gizleyebilirim de... fakat uzak duvarlardaki texture'lar sağa sola sallanıyor hatta bazen hepten yok oluyorlar, bu hiç hoş değil:
(https://i.hizliresim.com/G0RYQr.gif)
Bu haliyle 060 Amiga'mda 30-45 (hatta bazı açılarda 50) FPS elde ettim. Stock A1200'de ise 7-10 arası. Hala düşlediğim kadar iyi değil. :(
İşte denemelerimin ulaştığı nokta aşağı yukarı bu. Belki yalnız texture'lar için FLOAT kullanmayı deneyebilirim. Hayli uzun bir yazı oldu. Burada noktalasam iyi olur. Sabırla okuyan herkese iyi bayramlar dilerim. Görüşmek üzere. Sağlıkla kalın. :-*
Alıntı yapılan: Alpyre - 25 Haziran 2017, 21:26:29
Ray Casting kodumuzun hali hazırdaki haline zaten uygun değil.
Ray Casting dedi. Hemen @Wisdom 'ı sahneye davet ediyoruz.
http://retrojen.org/pano/index.php?topic=345.0 (http://retrojen.org/pano/index.php?topic=345.0)
Alıntı YapSabırla okuyan herkese iyi bayramlar dilerim. Görüşmek üzere. Sağlıkla kalın. :-*
Peki ya sabırla okumayan varsa... Onlara iyi bir bayramlar dilemiyor muyuz :)
Nacizane bir paylaşımda bulunayım bari bende. Amiga'daki çeşitli doom klonu fps oyunları üzerine güzel bir video derlemesi https://www.youtube.com/watch?v=Tv6aJRGpz_A (https://www.youtube.com/watch?v=Tv6aJRGpz_A)
Süper gelişiyor ellerine sağlık.
Alıntı Yapfakat uzak duvarlardaki texture'lar sağa sola sallanıyor hatta bazen hepten yok oluyorlar, bu hiç hoş değil:
Bu problemin başka bir bug olmadığından emin misin. mesela precision'ı 6 bit yerine 8 bite veya 16 bite çıkarınca bug ortadan kalkıyor mu? (Ayrıca 8 bit kullanırsan direk byte-sınırına geldiğin için bölme/shift yapmaya gerek kalmayabilir.
bir de aslında teknik olarak çok önemli değil ama texture tasarımı da burada önemli rol oynuyor. Bu tip texture renderer'larda texture'ın nasıl dizayn edildiği sonucu etkiliyor. Genel olarak fazla "yüksek frekanslı" tasarımlardan kaçınmak lazım. Bir texture ne kadar düşük frekanslı olursa bu tip nearest-neighbor türevi renderer'larda yaklaşıp uzaklaşırken o kadar iyi görünür. Mesela,
* duvar şu anda olduğu gibi 7 tuğla değil de 5 tuğla yükseklikte olsa. yani daha büyük tuğlalar ile (duvarın toplam yüksekliği aynı kalarak)
* bir piksel kalınlıkta tuğla sınırı çizgileri yerine tuğlanın tamamına gradient verirsen yani bİr tuğla şöyle birşey
***+++..
*****++.
*******+
*****++.
***+++..
Yani sözün özü bir piksel kalınlığında ve etrafından çok kontrastlı bir renkle ayrılan detaylar bazı uzaklıklarda kaybolacağı için bunun yerine hep gradientli şeyler kullanıyoruz
Çok detaylı yazamıyorum şu aralar. Aslında bu thread bayağı bir güzelleme hakediyor. Kusuruma bakmayın. Ama süper gidiyor.
Bu başlığa güncelleme zamanı! Geç cevaplar için özür. Şehir dışındaydım... :(
Alıntı yapılan: nightlord - 30 Haziran 2017, 01:52:13
Alıntı Yapfakat uzak duvarlardaki texture'lar sağa sola sallanıyor hatta bazen hepten yok oluyorlar, bu hiç hoş değil:
Bu problemin başka bir bug olmadığından emin misin. mesela precision'ı 6 bit yerine 8 bite veya 16 bite çıkarınca bug ortadan kalkıyor mu?...
Aynen abi. Duvarlara yaklaşınca oluşan bozulma precision'ı 10 bit'e çıkarınca ortadan kalkıyor. 16 bit'e ise hiç çıkarmak istemiyorum. Çünkü bazı hesaplamalarda precision'ı kaybetmemek için sola iki kez bitshift yapıyorum. Bu değişkenlerimi double yapmak zorunda bırakır. Bunu istemiyorum. Önerdiğin gibi 8 bit kullanıp, high word'ü doğrudan okumak süper olur. Yalnız C'de bunun için yazacağım kod ne kadar verimli olur bilemiyorum? Keşke Assembly bilsem. :D
Uzak duvarların kaybolmasının nedeni ise, mapping'de kullandığım bir değişkenin (her satırdaki duvar uzaklığı) de precise olması gerektiğindenmiş. Onu halledince o da düzeldi.
Bu arada görsellerden de anlaşılacağı gibi "perspective correct texture mapping" yapıyorum (her satırda duvar uzaklığı bu yüzden gerekli). Şehirlerarası yolda 90'lı yıllardaki öncü 3D oyunların görsellerini youtube'dan bol bol inceledim. "Legends of Valour" ve "Ultima Underworld" çok dikkatimi çekti. Bu ikisinin de PC versiyonu "perspective correct" kullanmıyor gibi. Affine kullanıyorlar sanki (bazı açılarda perspektif bozulmaları var çünkü texture'larda).
Ben de duvarları daha küçük duvarlara bölüp her duvar için Affine mapping yapmaya karar verdim.
(http://oi68.tinypic.com/2qtffjl.jpg)
Böylece satır başına birkaç çarpma bölme işleminden daha kurtulmuş oldum. Fakat bu defa da daha fazla vertex transform edilmek zorunda. Parça duvarların ve texture'ın genişliğini, perspektif bozulmasının fazla hissedilmeyeceği kadar büyütüp bir ortalama yakalamaya çalıştım. Hazır elim değmişken texture'ı da tümden değiştirdim. Belirttiğin gibi gradient'li bir şey yapmaya çalıştım. Gerçekten fark yarattı.
(http://oi68.tinypic.com/2gwvsj6.jpg)
NOT: Bu arada Legends of Valour'un Amiga sürümüne de baktım. Zemin döşemesini çıkarmışlar, fakat duvarlar "perspective correct"! Çok ilginç değil mi? :)
Bu haliyle FPS 060 Amiga'mda üst sınır olan 50'ye dayandı. Fakat duvarlara yakın olunduğunda (en az 25'e kadar) düşebiliyor.
Tüm bu optimizasyonlara rağmen, hala stok A1200'de bir Legends of Valour FPS performansını yakalayabilmiş değilim (Affine kullanmama rağmen 7-10 FPS'in üzerine çıkamadım hala). Bir şeyleri doğru yapmıyor olmalıyım.
Tahminimce hesaplamalarda değil de, pikselleri ekrana yazdırırken oluyor ne oluyorsa.
Ya da bu oyunlar Assembly ile yazıldığı için mi daha hızlı, bilemiyorum?
Bir de gcc ile mi derlesem acaba? Bakıcaz... :)
Denemelerim sürecek, bakalım daha neler öğreneceğim.
Alıntı yapılan: nightlord - 30 Haziran 2017, 01:52:13
Çok detaylı yazamıyorum şu aralar. Aslında bu thread bayağı bir güzelleme hakediyor. Kusuruma bakmayın. Ama süper gidiyor.
Yorumların hem fikir, hem gaz veriyor, hem de biraz şımartıyor abi. :)
Yoğun olduğunu biliyorum. Kıp kısa yazsan da hiç sorun değil. Zaten tek satırda bile 40 yıl düşünsem aklıma gelmeyecek fikirler veriyorsun. Çok sağol valla. :)
EDIT: Bir de executable atacaktım. Unutmuşum. Buyrun efendim.
Hareket için: W,A,S,D
Tam ekran : F
Çıkış : Q
Legends of Valour seninkinden yavaş çalışıyor gibi geldi bana alpyre.
stok a1200 üzerinde 7-17fps çiziyor.
Alıntı yapılan: Ref - 11 Temmuz 2017, 01:04:39
Legends of Valour seninkinden yavaş çalışıyor gibi geldi bana alpyre.
stok a1200 üzerinde 7-17fps çiziyor.
Aaa!? Gerçekten mi? Yani aslında öyle de olması gerek, çok daha sade bizimkisi.
Benim makinede 10'un üzerini göremedim bir türlü.
Ben A1200'ümde custom graphics.library'si olan bir ROM kullanıyorum, sanırım ondan bu farklılık.
İyisi mi yeni bir ROM yapayım şu makineye! :)
17 FPS hiç fena değil. Basit bir labirent oyunu yapabilirim öyleyse. :)
Selam Alpyre, hızlı iki sorum var?
Alıntı Yapmapping'de kullandığım bir değişkenin (her satırdaki duvar uzaklığı)
hemen bir terminoloji senkronizasyonu:
"satır" ile ne kastediyorsun? sanki dikey piksel sütunlarını (yani x=sabit) kastettiğini anlıyorum ama emin olamadım. yatay raster satırı (yani y=sabit) kastetmiyorsun değil mi?
Alıntı YapFakat bu defa da daha fazla vertex transform edilmek zorunda
senin vertexlerin 2d mi (yani üstten görünüş) 3d mi? transform işleminden kastın 3x3 (veya 3x2) bir matrix ile 2d bir vertex'in çarpılması mı? yoksa 4x4 (muhtemelen içine projection da yedirilmiş) bir matrix ile 3d bir vertex mi çarpıyorsun? ya da başka bir metod mu?
Hemen hızlı iki yanıt geliyor :)
Alıntı yapılan: nightlord - 12 Temmuz 2017, 21:14:53
Alıntı Yapmapping'de kullandığım bir değişkenin (her satırdaki duvar uzaklığı)
hemen bir terminoloji senkronizasyonu:
"satır" ile ne kastediyorsun? sanki dikey piksel sütunlarını (yani x=sabit) kastettiğini anlıyorum ama emin olamadım. yatay raster satırı (yani y=sabit) kastetmiyorsun değil mi?
Haklısın. 'Satır' hiç doğru bir terminoloji olmadı. "Sütun" demeliydim (x=sabit). Duvarlar sırayla düşey çizgiler halinde çiziliyor.
Alıntı yapılan: nightlord - 12 Temmuz 2017, 21:14:53
Alıntı YapFakat bu defa da daha fazla vertex transform edilmek zorunda
senin vertexlerin 2d mi (yani üstten görünüş) 3d mi? transform işleminden kastın 3x3 (veya 3x2) bir matrix ile 2d bir vertex'in çarpılması mı? yoksa 4x4 (muhtemelen içine projection da yedirilmiş) bir matrix ile 3d bir vertex mi çarpıyorsun? ya da başka bir metod mu?
Bak işte bu soru çalıştığım yerden geldi.
Dün şu yazını okumuş bulundum (sörf yaparken şans eseri karşıma çıktı): http://www.plazma-dergi.org/dergi/08/chunk/ch09.html (http://www.plazma-dergi.org/dergi/08/chunk/ch09.html)
Okumamış olsaydım şimdi şaşkın şaşkın ekrana bakıyor olacaktım muhtemelen. :) Neyse...
Vertex'lerim tamamen 2D. X ve Y koordinatından ibaret.
'Transform' dediğim ise bu vertex'lerin herbirini oyuncuya rölatif hale getirmek (sanki oyuncu sabit duruyor da tüm duvarlar onun etrafında dönüyor gibi).
Pseudo code olarak yazarsam şöyle bir şey yapıyorum:
pX,PY : Oyuncunun mutlak haritadaki konumu
X,Y : Vertex'lerin mutlak haritadaki koordinatları.
TX,TY : Oyuncuya göre rölatif hale getirilmiş koordinatlar.
for each vertex in this sector
vertex.TX = vertex.X - pX
tempTY = vertex.Y - pY
vertex.TY = vertex.TX * Cos(angle) + tempTY * Sin(angle)
vertex.TX = vertex.TX * Sin(angle) - tempTY * Cos(angle)
Daha sonra da bu TX,TY koordinatlarından vertex'lerin ekran koordinatlarını hesaplıyorum. TY bir aproksimasyon olarak oyuncuya uzaklık (z) kabul ediliyor (bu bisqwit'in kodunun aşağı yukarı aynısı).
Bu hesaplamalar için matris kullanabileceğimi yeni öğrendim (dün :)).
Hatta bisqwit'in videosundaki gizemli "Vector Cross Product" işleminin olduğunu da sanırım anladım. Vertex'leri vektör olarak alıyor, matris olarak yazıyor ve sonra ardışık matris işlemleri yapıyor. Ama giriş yazımda da dediğim gibi, bu çok daha pahalı. Temel trigonometri ile çok daha ucuz hesaplanabiliyor.
Ancak 'transform' işleminde avantaj sağlayabilir gibi duruyor. Bunun üzerine biraz kafa yorayım.
OK bu durumda vertex transform sayısını azaltmanın bir yolu olabilir. Özellikle duvarları küçük küçük bölümlediğin için (hani mesela 8m uzunluğundaki duvarı 8 tane 1m duvar yapıyorsun ya)
Diyelim ki 8 m duvar için 9 vertex'in var.
v1, ... , v9
ve sen bunları transform edip 9 transformed vertex buluyorsun
tv1, ... , tv9
Bu yazdığın işlem ile sadece ilk 2 vertexi döndür.
tv1, tv2 yi bul
sonra bu ikisinin farkı senin o yöndeki duvarlar için birim vektörün
u1 = tv2 - tv1
bundan sonra
tv3 = tv2 + u1
tv4 = tv3 + u1
...
tv9 = tv8 + u1
yani 7 tane vertex'i sadece 2 toplama ile bulabilirsin.
Hatta en başta hatırlarsan bunu sormuştum. Mesela bütün duvarlar kuzey güney ve doğu batı şeklinde olsa işine yarar mı diye. Bunun için sormuştum. Çünkü o durumda sadece 2 tane birim vektör hesaplaman yeterli diğer bütün vertexleri toplamalar/çıkarmalar ile transform edebilirsin.
Merhaba,
Cok guzel gidiyor, elinize saglik, ben daha yeni gordum bu konuyu. Koda bakmadim ama konunun tamamini okudum, bir yerde sin/cos tablolarini 72 degerden 18'e indirdiginizi yazmistiniz galiba (simdi geri donup bakamadim). Eger programin size'i sorun degilse (ki degil saniyorum), bu tablolari mumkun oldugunca acmanizda ve bir fonksiyon uzerinden erismek yerine inline olarak erismenizde fayda var. Hatta yeriniz varsa mumkun oldugunca her turlu hesaplamayi tablolara donusturmenizi oneririm. Cok genel bir oneri oldu biliyorum, belki zaten yaptiniz, belki de "feasible" degil, ama soylemeden gecemedim.
Tekrar elinize saglik, basarilar!
Alıntı yapılan: nightlord - 13 Temmuz 2017, 19:55:05
Hatta en başta hatırlarsan bunu sormuştum. Mesela bütün duvarlar kuzey güney ve doğu batı şeklinde olsa işine yarar mı diye. Bunun için sormuştum. Çünkü o durumda sadece 2 tane birim vektör hesaplaman yeterli diğer bütün vertexleri toplamalar/çıkarmalar ile transform edebilirsin.
hmm bu durumda wolfenstein topu topu 2 vertex hesabından ibaret miymiş?
e bu güzel bir ip ucu oldu.
Alıntı yapılan: Wisdom - 15 Temmuz 2017, 12:44:09
...bu tablolari mumkun oldugunca acmanizda ve bir fonksiyon uzerinden erismek yerine inline olarak erismenizde fayda var. Hatta yeriniz varsa mumkun oldugunca her turlu hesaplamayi tablolara donusturmenizi oneririm...
Haklısın Wisdom. Öyle yapacağım.
Ancak nightlord'un önerdiğini uygulamanın zarif bir yolunu düşünüyorum kaç gündür. Bu optimizasyon kodumda kesinlikle olsun istiyorum ama haritalarım Wolf3D'deki gibi blok blok olsun da istemiyorum. Pek çok şeyi yeni baştan tasarlayacağım sanırım. :)
Alıntı yapılan: Alpyre - 17 Temmuz 2017, 17:02:28
Wolf3D'deki gibi blok blok olsun da istemiyorum. Pek çok şeyi yeni baştan tasarlayacağım sanırım. :)
bu durumda harita detayını limitleyerek çözebilirsin belki de: 90,60,45,30 derecelik duvarlar kullanıp bunları kendi aralarında toplam 8 vertex çarpımı ile taban işlemi halledip, diğer tüm duvarları kendi gruplarında toplama yöntemi ile halledebilirsin. Hatta sadece 90 ve 45 derece kullandığında bile birçok harita başarıyla kotarılabilir.
Evreka. :)
Günlerce kafamdaki düşünce deneyleri yüzünden evde ve işte hayalet gibi gezinmelerimin sonunda tüm detaylar birbiriyle örtüştü ve neyi nasıl yapacağımı buldum.
Harita biçemimden ana loop'uma kadar pek çok şey baştan yazılacak şimdi. Bakalım artı kaç FPS elde edeceğim. :)
Alıntı yapılan: Ref - 18 Temmuz 2017, 23:31:15
...tüm duvarları kendi gruplarında toplama yöntemi ile halledebilirsin....
Bir ipucu: İlk bunu düşündüm ama sonra daha da iyisini bulup vazgeçtim. Çalışırsa detaylıca açıklayacağım nasıl hallettiğimi. :)
Yeniden merhabalar arkadaşlar. Nerede kalmıştık? :)
nightlord'un dediğini (biraz da abartarak) uygulamaya çalıştım.
Haritayı yüklerken her bir duvarın hangi yöne uzandığını tespit edip duvarın bir attribute'si olarak her duvara ekledim (şimdilik sadece DOĞU-BATI-KUZEY-GÜNEY yönleri var, dilersem daha sonra ara yönler de eklemek kolay).
Sonra iki tane birim duvar parçası uzunluğunda vektör oluşturdum. Biri Doğu->Batı diğeri Kuzey->Güney yönünde.
Her karede sadece bu iki vektörü ve içinde bulunulan odanın (sector) ilk duvarının, ilk vertex'ini açıya göre sin(), cos() değerleriyle çarparak dönüştürüyorum.
Harita verisinde her odanın, her bir duvarını saat yönünde ve sırayla tanımlayınca, her duvar parçasının bittiği yerde diğeri başlamış oldu. Böylece tüm duvarların dönüştürülmüş ikinci vertex'ini uzandıkları yönün vektörünü ekleyerek hesaplayabildim.
İlk vertex ise zaten hep bir önceki duvardan miras kalıyor. Yani ilk 3 dönüştürmeden sonra tüm diğer vertex'ler sadece toplama ile hesaplanıyor.
Bir önemli değişiklik de texture bitmap'lerini eğer varsa FastRAM'e yüklenecek şekilde ayarlamak oldu (ayrıca birden çok texture da ekledim - gerçi hepsi birbirine benziyor şimdilik :) ).
Böylelikle FPS turbo kartlı Amiga'larda (030, 040, 060 da farketmiyor ilginç ki) 25-50 FPS arasına dayandı. Bu çok iyi.
Ancak stok Amiga'larda 3-10 FPS. :)
Bu Citadel'i, Gloom'u, AB3D'yi falan zamanında (yavaş diye) beğenmemiştik ama gördüğüm kadarıyla Amiga'ya bu oyunları yapan programcılar oldukça ustalık konuşturmuş.
Copper çipini "Chunky to Planar" dönüşümü yapacak şekilde programlamanın yolları olduğuna dair bir şeyler okudum. Anladığım kadarıyla bundan yararlanmışlar. Görünen o ki yolun bundan sonrasına katırlarla (low level assembly ile) devam etmek gerekecek.
Biraz daha karmaşık bir harita ile son derlenmiş çalıştırılabiliri ekliyorum. Ha bu arada bir harita editörü de geliştirmek gerek. Elle yazmak zor olmaya başladı. :)
Kaynak kodlar için de buraya bakabilirsiniz: https://github.com/alpyre/DLE
Görüşmek üzere...
Alpyre, bugün yeni bir trick öğrendim, wolf3d ve o dönemin oyunlarında kullanılmış vasit bir trick.
Buna göre k/g duvarlar aydınlık, doğu/batı duvarlar karanlık. Böylece bir ışık ilüzyonu oluşuyor.
Sanırım bu daha fazla açı kullandığında da farklı texturelarla da halledilebilir.
Her duvarın bir propertysi olduğuna göre eklemen mümkün olabilir belki.
Ayrıca 7-10 iyi bir rakam aslında. C kodundan üreyen asm koduna da göz atmak iyi olabilir. Fakat amiga demoscene hilelerini kullanmadan o rakam 15-20 aralığına çıkmaz gibi...
(https://s4.postimg.org/8m325hf6x/20170819_224312.jpg) (https://postimg.org/image/8m325hf6x/)
Alpyre şu an çok kısa bir mesaj yazabiliyorum. Ama koda çok hızlıca bir göz attım. ve pek çok yerde linked list'ler içine atılmış içinde ID barındıran nesneler kullanıyorsun. Bunların mümkün olanlarını düz arraylere yerleştirip ID kavramını da her nesnenın içinde olduğu arraydeki indisi ile değiştirmen sana bütün traversallarda hız kazandırıp, bütün findXXX metodlarında da O(n)'den O(1)'e gitmeni sağlayabilir.
Yani findVertex(foo) yerine vertices[foo]
Eğer hızlıca bakarken bunun böyle olmasını gerekli kılan birşeyleri gözden kaçırmışsam ignore :)
Şey... Şimdi 'find' fonksiyonlarım sadece haritayı yüklerken kullanıliyor. Duvarları çizen ana döngüde çağırılmıyorlar. Her bir vertex'e, duvar'a vs. doğrudan pointer'ı ile erişiliyor orada.
Böyle yapmamın nedeni okuduğum bir makalede Array erişimlerinde her zaman 1 çarpma işlemi yapıldığı, pointer'la erişimin bu nedenle daha hızlı olacağı idi (ne kadar doğrudur bu bilmiyorum gerçi).
Amiga (exec) listlerinde traverse işlemi de tamamen pointer erişimi bu arada (harita allokasyonlarının dinamik olmasını sağlaması da cabası).
Doğru bir şey mi yapmışım? :)
erişimleri yine pointer ile yapabilirsin. yani birileri 10. duvara erişecekse onlara &walls[10] verebilirsin ve ondan sonrası aynı olur. Lakin bunların bellekte rastgele dağılıp içlerinde id fieldı tutuyor olmalarının çok avantajını göremiyorum. yani nesneleri arraylerde tutup, findFoo'ları Foo[] ile (yani lineer search yerine tek çarpma ile) değiştirip, data structure hieararchisinde pointer kullanmaya devam etsen sanki best of both worlds olacak
Eğer array'de traverse yaparken her iterasyonda a[] nin sana bir çarpma getirmesinden korkuyorsan o döngüler de şöyle yazılabilir:
for (A* ia = a; ia != a + count; ++ia){
// do stuff with ia
}
böylece her iterasyonda bir toplama yapmış olursun (ki bunu compiler'ın becerebiliyo olmasını beklerim ama belki amiga zamanı compilerları geride kaldı)
Mevzuya bir saplama yapıp gideyim.
Baba adamlardan Fabien Sanglard (http://fabiensanglard.net/)'ın yeni kitabı Game Engine Black Book: Wolfenstein 3D (https://www.amazon.com/Game-Engine-Black-Book-Wolfenstein/dp/1539692876) tam da bu mevzuyla ilgili. Tabi bu mevzudakinden biraz farklı olarak olaylar x86/vga diyarlarında geçiyor.
Önsözünü de baba adamların feriştahı John Carmack yazmış.
Başka projelere dalıp burayı çok ihmal ettim. Ama dün aminet'te Breathless (http://www.lemonamiga.com/games/details.php?id=227)(1996) oyununun kaynak kodları (http://aminet.net/package/game/shoot/Breathless-1996-Source) yayınlanmış.
Bu oyunun grafikleri bayağı iyi ve FPS'si de hiç fena değildi. Gördüğüm kadarıyla C'de yazılmış. Kopya çekmek için bir sürü materyalim oldu. Bakıcaz artık. :)
EDIT: MapEditor C imiş. Oyun kodu Assembly çıktı. :(
Bu ray casting işini anlatan güzel bir videoya rastladım, güzel anlatmış :D
Burada durması daha iyi...
https://www.youtube.com/watch?v=eOCQfxRQ2pY&t=2s