Kendi sahne grafiğimi haddeleme


23

Merhaba Oyun Geliştirme SE!

Basit ve çok hafif bir oyun motoru yaratma umuduyla OpenGL'de yoluma giriyorum . Projeyi, sonunda biraz para kazanabilecek, ancak her iki şekilde de eğlenceli olacak bir öğrenme deneyimi olarak görüyorum.

Şimdiye kadar bazı temel G / Ç'leri, bir pencereyi (çok şık bir F11 tam ekran tuşuyla) ve tabii ki bir OpenGL bağlamı elde etmek için GLFW kullandım. Ayrıca, Windows kullanıyorum ve tüm OpenGL 3.0 + 'ı kullanmak istediğim için OpenGL uzantılarının kalanını ortaya çıkarmak için GLEW kullandım.

Bu da beni sahne grafiğine getiriyor. Kısacası, kendim atmak istiyorum. Bu karar OSG'ye baktıktan ve sahne grafiği konseptinin nasıl büküldüğü, büküldüğü ve kırıldığı hakkında birkaç makale okuduktan sonra geldi. Böyle bir makale , sahne grafiğinin nasıl geliştiğini açıkladı ...

Daha sonra bazı süs eşyalarının güzel sulu biftek olması ve bazı canlı inekler olması dışında, Noel ağacına süs eşyaları asmak gibi tüm bu ekstra şeylere ekledik.

Analojiyi takiben, biftek, bir sahne grafiğinin ne olması gerektiğinin etini, ekstra kod yığınlarına ya da tüm ineklere bağlamak zorunda kalmadan istiyorum.

Bu nedenle, kendimi bir sahne grafiğinin ne olması gerektiğini ve basit bir sahne grafiğinin nasıl uygulanması gerektiğini merak ediyorum. İşte şimdiye kadar elimde olan şey ...

Bir ebeveyn, n çocuk ağacı veya DAG ki ...

  • Oyun nesnesi dönüşümlerini (pozisyon, rotasyon, ölçek) takip etmeli
  • İyileştirmeler için oluşturma durumlarını tutmalı
  • Frustum görünümünde olmayan nesnelerin toplanması için bir araç sağlamalıdır.

Aşağıdaki özelliklerle ...

  • Tüm düğümler hatırı sayılır olarak değerlendirilmelidir (yapmasalar bile) Bu, onlar ...

    • Hepsinde cull (), state () ve draw () yöntemleri varsa (görünmüyorsa 0 döndür)
    • cull (), tüm çocuklar için tekrarlı olarak cull () öğesini çağırır, böylece tüm düğüm ve tüm çocuklar için tam bir cull mesh oluşturur. Başka bir yöntem, hasChanged (), statik kafeslerin denilen, culling geometrilerinin her bir kareyi hesaplamasına gerek duymamalarını sağlayabilir. Bu, eğer alt ağaçtaki herhangi bir düğüm değişmişse, köke kadar tüm geometri yeniden inşa edilecek şekilde çalışacaktır.
  • Render durumları basit bir numaralandırmada tutulacak, her düğüm bu numaralandırmadan istediği bir OpenGL durumu ayarlayacaktır ve bu durum o düğüm üzerinde draw () çağrılmadan önce ayarlanacaktır. Bu, kümelemeye izin verir, belirli bir durum kümesinin tüm düğümleri birlikte işlenir, ardından bir sonraki durum kümesi kurulur ve böyle devam eder.

  • Hiçbir düğüm doğrudan geometri / gölgelendirici / doku verilerini içermemelidir, bunun yerine düğümler paylaşılan nesnelere işaret etmemelidir (belki bir kaynak yöneticisi gibi bazı singleton nesneler tarafından yönetilebilir).

  • Sahne grafikleri gibi durumları izin vermek için (belki bir proxy düğümü olarak kullanılarak) diğer sahne grafikleri referans mümkün olmalıdır , bu dolayısıyla modelleri, çok örgü kompleksi / veri bir ton eklemeden sahne grafiğinin çevresinde kopyalanacak nesneleri sağlayan.

Mevcut tasarımım hakkında değerli geri bildirimler almayı umuyorum. Eksik işlev mi? Çok daha iyi bir yol / tasarım deseni var mı? Biraz basit bir 3D oyun için bu tasarıma dahil edilmesi gereken daha büyük bir kavramı özlüyor muyum? Vb.

Teşekkürler -Cody

Yanıtlar:


15

Kavram

Temel olarak, bir sahne grafiği, hiyerarşik olarak yapılandırılmış bir mekansal ilişki kümesini temsil eden iki yönlü bir asiklik grafikten başka bir şey değildir.

Vahşi doğada motorlar, belirtildiği gibi sahne grafiğine başka güzellikler ekleme eğilimindedir. Bunu et ya da inek olarak görüp görmemeniz, muhtemelen oradaki motor ve kütüphanelerdeki deneyiminize bağlıdır.

Hafif tutmak

Sahne grafiği düğümünüzün (kalbinde, uzamsal / topografik bir yapıdan ziyade topolojik bir yapıdır) sahip olduğu Unity3D stilini doğal olarak uzamsal parametreleri ve işlevselliği içeren olarak tercih ediyorum. Motorumda düğümlerim Unity3D'den bile daha hafiftir, burada süper sınıflardan / uygulanmış arayüzlerden pek çok gereksiz önemsiz üyeyi miras alırlar: İşte sahip olduklarım - alabildiğiniz kadar hafif:

  • ebeveyn / çocuk işaretçi üyeleri.
  • dönüşüm öncesi uzaysal parametre üyeleri: xyz konumu, eğim, yalpa ve yuvarlanma.
  • bir dönüşüm matrisi; hiyerarşik bir zincirdeki matrisler, ağacı tekrar tekrar yukarı / aşağı yürüterek çok hızlı ve kolay bir şekilde çoğalabilir ve size bir sahne grafiğinin ana özelliği olan hiyerarşik mekansal dönüşümleri verir;
  • yalnızca bu düğümün dönüşüm matrislerini updateLocal()güncelleyen bir yöntem
  • bunu ve tüm soyundan gelen düğümleri updateAll()güncelleyen bir yöntem 'matrisleri dönüştürür

... ayrıca hareket denklemleri mantığı ve böylece düğüm sınıfımda hız / ivme üyelerini (doğrusal ve açısal) dahil ediyorum. Bundan vazgeçebilir ve isterseniz ana denetleyicinizde kullanabilirsiniz. Ama işte bu - gerçekten çok hafif. Unutma, bunları binlerce varlığa sahip olabilirsin. Önerdiğin gibi hafif tut.

Hiyerarşi Oluşturma

Diğer sahne grafiklerine atıfta bulunan bir sahne grafiği hakkında söyledikleriniz ... Yumruk çizgisini bekliyorum? Tabii ki yaparlar. Ana kullanımları bu. Herhangi bir düğümü başka bir düğüme ekleyebilirsiniz ve yeni dönüşümün yerel alanı içinde dönüşümler otomatik olarak yapılmalıdır. Tek yaptığınız bir işaretçi değiştirmek, etrafındaki verileri kopyaladığınız gibi değil! Bir işaretçiyi değiştirerek, daha derin bir sahne grafiğine sahip olursunuz. Proxy'leri kullanmak işleri daha verimli hale getirirse, elbette, ama ihtiyacı hiç görmedim.

Render ile İlgili Mantıktan Kaçının

Sahne grafiği düğüm sınıfınızı yazarken görüntülemeyi unutun, yoksa kendiniz için şeyleri karıştırırsınız. Önemli olan şey, bir veri modeline sahip olmanız - sahne grafiği olsun ya da olmasın - ve bazı uygulayıcılar bu veri modelini inceleyecek ve dünyadaki nesneleri buna göre inceleyecekler, 1, 2 , 3 veya 7 boyut. Yaptığım nokta şudur: Sahne grafiğinizi render mantığı ile kirletmeyin. Bir sahne grafiği, topoloji ve topografya ile ilgilidir - yani bağlantı ve mekansal özellikler. Bunlar simülasyonun gerçek halidir ve oluşturma yokluğunda bile vardır (bu, güneşin altında herhangi bir şekilde birinci şahıs görüşünden istatistiksel grafiğe metinsel bir tanımlamaya kadar herhangi bir şekilde olabilir). Düğümler oluşturma ile ilgili nesnelere işaret etmez - ancak bunun tersi doğru olabilir. Ayrıca şunu da düşün: Tüm ağacınızdaki her sahne grafiği düğümü tanınmaz. Birçoğu sadece konteyner olacak. Öyleyse neden bir gösterici-render-nesnesi için bellek ayırıyor? Hiç kullanılmamış bir işaretçi üyesi bile hafızayı alıyor. Bu yüzden işaretçi yönünü tersine çevirin: Render ile ilgili örnek veri modeline (sahne grafiği düğümünüz olabilir veya dahil olabilir) tam tersi DEĞİLDİR. Ve, denetleyici listenizde ilerlemenin kolay bir yolunu ancak ilgili görünüme erişmeyi istiyorsanız, O (1) okuma zamanına yaklaşan bir sözlük / karma tablo kullanın. Bu şekilde herhangi bir kirlenme yoktur ve simülasyon mantığınız hangi üreticilerin yerinde olduğu ile ilgilenmez, bu da günlerinizi ve gecelerinizi kodlar. Öyleyse neden bir gösterici-render-nesnesi için bellek ayırıyor? Hiç kullanılmamış bir işaretçi üyesi bile hafızayı alıyor. Bu yüzden işaretçi yönünü tersine çevirin: Render ile ilgili örnek veri modeline (sahne grafiği düğümünüz olabilir veya dahil olabilir) tam tersi DEĞİLDİR. Ve, denetleyici listenizde ilerlemenin kolay bir yolunu ancak ilgili görünüme erişmeyi istiyorsanız, O (1) okuma zamanına yaklaşan bir sözlük / karma tablo kullanın. Bu şekilde herhangi bir kirlenme yoktur ve simülasyon mantığınız hangi üreticilerin yerinde olduğu ile ilgilenmez, bu da günlerinizi ve gecelerinizi kodlar. Öyleyse neden bir gösterici-render-nesnesi için bellek ayırıyor? Hiç kullanılmamış bir işaretçi üyesi bile hafızayı alıyor. Bu yüzden işaretçi yönünü tersine çevirin: Render ile ilgili örnek veri modeline (sahne grafiği düğümünüz olabilir veya dahil olabilir) tam tersi DEĞİLDİR. Ve, denetleyici listenizde ilerlemenin kolay bir yolunu ancak ilgili görünüme erişmeyi istiyorsanız, O (1) okuma zamanına yaklaşan bir sözlük / karma tablo kullanın. Bu şekilde herhangi bir kirlenme yoktur ve simülasyon mantığınız hangi üreticilerin yerinde olduğu ile ilgilenmez, bu da günlerinizi ve gecelerinizi kodlar. Ve, denetleyici listenizde ilerlemenin kolay bir yolunu ancak ilgili görünüme erişmeyi istiyorsanız, O (1) okuma zamanına yaklaşan bir sözlük / karma tablo kullanın. Bu şekilde herhangi bir kirlenme yoktur ve simülasyon mantığınız hangi üreticilerin yerinde olduğu ile ilgilenmez, bu da günlerinizi ve gecelerinizi kodlar. Ve, denetleyici listenizde ilerlemenin kolay bir yolunu ancak ilgili görünüme erişmeyi istiyorsanız, O (1) okuma zamanına yaklaşan bir sözlük / karma tablo kullanın. Bu şekilde herhangi bir kirlenme yoktur ve simülasyon mantığınız hangi üreticilerin yerinde olduğu ile ilgilenmez, bu da günlerinizi ve gecelerinizi kodlar.dünyalar daha kolay.

Çıkarma gelince, yukarıya bakın. İlgi alanı toplama işlemi bir simülasyon mantığı konseptidir. Başka bir deyişle, dünyayı bunun dışında (genellikle kutulu, dairesel veya küresel) alanın dışında işlemezsiniz. Bu, oluşturma gerçekleşmeden önce ana denetleyici / oyun döngüsünde gerçekleşir. Öte yandan, frustum culling tamamen render ile ilgilidir. Öyleyse şu anda toplanmayı unut. Sahne grafikleriyle hiçbir ilgisi yok ve ona odaklanarak elde etmeye çalıştığınız şeyin gerçek amacını gizlemiş olacaksınız.

Son bir not ...

Burada bulunan görüntü oluşturma ile ilgili tüm ayrıntılar göz önüne alındığında, bir Flash (özellikle AS3) arkaplanından geldiğinize dair güçlü hisler alıyorum. Evet, Flash Stage / DisplayObject paradigması, senaryoun bir parçası olarak tüm oluşturma mantığını içerir. Ancak Flash, mutlaka yapmak istemediğiniz birçok varsayımda bulunur. Tam teşekküllü bir oyun motoru için, performans, kolaylık ve uygun karmaşıklıkta SoC ile kod karmaşıklığının kontrolü için ikisini karıştırmamak daha iyidir .


1
Sağol Nick. Aslında bir 3D animatörüyüm (gerçek 3B flash değil) programcı oldum, bu yüzden grafik olarak düşünmeye meyilliyim. Yeterince kötü değilse, Java’ya başladım ve kendimi o dilin içine yerleştirilmiş “her şey bir nesne olmalı” zihniyetinden merak ediyorum. Beni sahne grafiğinin oluşturma ve kodlama kodundan ayırması gerektiğine ikna ettiniz, şuan dişlilerim bunun tam olarak nasıl yapılması gerektiğine bağlı. Dönüştürücüye, dönüşüm verileri vb. İçin sahne grafiğini referans veren kendi kendine özgü bir sistem gibi davranmayı düşünüyorum.
Cody Smith

1
@CodySmith, Yardım ettiğine sevindim. Utanmaz fiş, ancak SoC / MVC ile ilgili bir çerçeve yapıyorum . Bunu yaparken, her şeyin merkezi ve yekpare bir nesne içinde olması gerektiğinde ısrar eden, sektördeki daha geleneksel kampla patlamaya geldim. Fakat onlar bile genel olarak size söylerlerdi - sıranızı sahne grafiğinizden ayrı tutun. SoC / SRP, yeterince vurgulayamayacağım bir şey - asla ihtiyaç duyduğunuzdan daha fazla tek bir sınıfa mantık karıştırmayın. Kafamın içine bir silah koyarsanız, karmaşık OO miras zincirlerini aynı sınıftaki karışık mantık üzerine bile savunurdum!
Mühendis

Hayır, konsepti beğeniyorum. Ve senin hakkın, bu yıllardır oyun tasarımı hakkında okuduğum her yerde gördüğüm SoC'nin ilk sözü. Tekrar teşekkürler.
Cody Smith,

@CodySmith Bunu tekrar gözden geçirirken hızlıca düşündüm. Genel olarak işleri yoluna sokmak iyidir. Render tabi senin kod temeli model kontrolör nesnelerin çeşitli türleri için, ancak, bir sen koleksiyonları tutmak için ince Renderableolanlar çekirdek model kontrolör nesnelere içten (bir arayüz veya soyut sınıf olan) s. Bunun iyi örnekleri varlıklar veya UI öğeleridir. Böylelikle, yalnızca varlık sınıfını kirletecek uygulama özellikleri olmadan, dolayısıyla arayüzlerin kullanımına gerek kalmadan, yalnızca söz konusu çekirdek nesneye uygun olan işverenlere hızlı bir şekilde erişebilirsiniz.
Mühendis

@CodySmith Yararı, örneğin olabilecek varlıklar ile açıktır. Hem dünya görünümünde hem de harita üzerinde temsiller yapabilir. Dolayısıyla, koleksiyon. Alternatif olarak, dahili olarak o nesneye, her model denetleyici nesnesi için yalnızca tek bir işleyici yuvasına izin verebilirsiniz. Ancak arayüzü genel tutun! Spesifikasyon yok - sadece Renderer.
Mühendis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.