Erhan Ballıeker

UrhoSharp ve Xamarin Workbook

Herkese Merhaba,

Bir önceki yazımızda Urhosharp’ın ne olduğundan ve bu kütüphaneyi kullanmak için bilmemiz gereken temel terimlerden bahsetmiştik. Bu yazımızda da bu terimleri kullanarak, Xamarin Workbook ile bir kaç örnek yapacağız. Örnekleri Workbook ile yapmayı seçmemin sebebi, hem Xamarin Workbook u biraz tanıtmak ve ne kadar kullanışlı olduğunu göstermek, hem de kod tarafında yaptığımız en küçük değişiklikleri anında görmek, telefona deploy etmenin verdiği zaman kaybından kurtulmak.

Tamamen ücretsiz ve çok kullanışlı olan Xamarin Workbook’u hem windows hem de  Mac için buradan indirebilirsiniz. Örnekleri inceleyebilir ve geri bildirimlerde bulunabilirsiniz.

workbook

Xamarin Workbook’u bilgisayarımıza indirip kurduğumuzda yandaki şekilde gördüğümüz gibi bir ikonla karşımıza çıkıyor.Bu ikona tıklayarak Workbook u açıyoruz.

workbooktemp

Workbook u ilk açtığımızda karşımıza bir template seçim ekranı geliyor. Burada Android, iOS, WPF, Console (.Net Framework veya .Net Core )seçimi yaparak workbook u hazırlıyoruz. Ben bu örneğimizde Console (.Net Framework) seçerek ilerliyeceğim.

Artık seçimlerimizi yapıp boş bir Workbook açmış olduk. Bu ekranda yapabileceklerimizden biraz bahsedip, örneğe giriş yapacağım.

workbookfile

Sol tarafta, workbook’u oluşturduğumuz ismin altında iki adet tab mevcut. Biri NuGet packages, diğeri kodlarımızı ve notlarımızı yazacağımız workbook’umuz. Tıpkı Visual Studio dan alışık olduğumuz gibi istediğimiz Nuget Package ı projemize ekleyip, projemizde kullanabiliyoruz. Hemen orta bölümde ise, workbook’umuzun kendisi mevcut, boş bir Executable cell ile gelmiş halde duruyor.  Workbook’a iki farklı satır(cell) ekleyebiliriz. Bunlardan biri Executable C# Cell bir diğeri de Documentation Cell. Her bir hücrenin en alt sağ tarafında, 3 buton mevcut. Bu butonları kullanarak, ilgili hücreyi silebilir, yeni bir dökümantasyon yada C# executable cell ekleyebiliriz. eklediğimiz hücre eğer çalıştırılabilir C# hücresi ise, hemen sol alt tarafında bir play butonu görüyor olacağız. Bu  butona bastığımızda, o hücre çalışacak ve bize o blokta ki çıktıyı (genellikle aynı hücre içerisinde en son satırda yazdığımız kodun çıktısı) hemen hücrenin altında bize gösterecek.

Workbook ile çalışırken dikkat etmemiz gereken önemli bir konu var. yukarıda bahsettiğim gibi, her bir executable cell çalıştığında, çıktıyı bize alt tarafında gösterecek, yani her bir hücrenin geriye birşey dönmesi gerekli. Normalde, Visual Studio kullanarak bir UrhoSharp örneği yapmaya kalkışsak, kendi Application objemizi, Urho.Application sınıfında türetip, gerisini bu application sınıfına bırakırdık. Bu miras aldığımız Application objesi, bizim kendi application objemiz içerisindeki “Run” methodunu tetikleyip, uygulamamızı başlatır, ve biz bir şekilde uygulamayı kapatmadığımız sürece de durdurmazdı. “Run” methodu da blocker bir method olduğundan, Workbook’ta kullanıma uygun değil malesef. Ama tam olarak bu workbook’ta kullanımımıza sunulmuş bir nesne var. SimpleApplication nesnesi bizim için, bazı initialization işlemlerinden sonra, bize bir application nesnesi dönüyor ve bunun üzerinden işlemlerimizi yapmaya devam edebiliyoruz.Bununla da kalmıyor, bizim için bir Camera, Light ve bir RootNode u üretmiş olarak kullanımımıza sunuyor.

Bir diğer dikkat etmemiz gereken konu ise, Workbook içerisindeki her bir executable cell tekrar tekrar çalışabilir olduğundan, uygulamamızda yapacağımız bazı işlemlerin, öncesinde tersini yapmamız gerekecek. Örneğin, Scene’imize bir node eklemeden önce o node u sileceğiz, veya bir event tanımladığımızda onun öncesinde de biraz reflection kullanıp kaldırmamız gerkecek. Bu tarz küçük handikapların dışında, workbook ile çalışmaya başladığınızda, özellikle yeni bir şeyi öğrenme konusunda ne kadar işe yarar olduğunuz göreceksiniz.

urhopackage

Artık örneğimize geçebiliriz. Nuget Packages‘a sağ tıklayıp, “Add Pacakge…” butonuna basarak karşımıza gelen ekrandaki Search kısmına UrhoSharp yazıyoruz ve UrhoSharp1.5.22 paketini çift tıklayarak yada alt taraftaki Add Package butonuna basarak Workbook’umuza ekliyoruz.

Bu paketi projemize eklediğimizde, ilk executable cell imizde #r “Urho” şeklinde ilgili kütüphanenin referansının workbook a eklendiğini göreceğiz. Bir Executable daha açıp, workbook’ta kullanacağımız namespace’leri ekliyoruz. Bu örneğimizde sadece Urho namespace’i yeterli olacak. Ctrl + Enter ‘a basarak veya hücrenin altındaki play butonuna basarak ilgili hücreyi çalıştırabiliriz. Workbook bizim için yeni bir executable cell oluşturacaktır. kod yazarken bir sonraki satıra geçmek için Shift + Enter’a basabiliriz.

newapp

Namespace’imizi ekledikten sonra. Bahsettiğimiz SimpleApplication sınıfının static Show metodunu kullanarak kendimize, belirttiğimiz boyutlarda bir 3D canvas açıyoruz. bundan sonraki her işlemimizi bu canvas üzerinde göreceğiz. Static Show metodu bizden bir application options nesnesi bekliyor. Yeni ApplicationOptions oluşturup, canvasımıza istediğimiz width ve height ı verip canvas ı oluşturuyoruz.

Bu örneğimizdeki amacımız ekrana sadece basit bir çizgi çizmek =) Bunu yaparken bir önceki yazımızda bahsettiğimiz terimlerin nasıl kullanıldığını göreceğiz. Sonraki örneklerimiz daha komplike olacağından, bu terimleri kullanmaya alışmamızda fayda var.

Öncelikle, boş uzayda bir çizgi çizmek için ihtiyacım olan iki noktayı tanımlayacağım. Sonrasında bu noktaları VertexBuffer nesnesinde birleştirip, devamında Geometry, Model, Material, StaticModel, Component ve Node sınıflarını kullanarak, bu çizgimizi canvas’ta göstereceğiz.

VertexBuffer.PositionNormal[] vertices = {
    new VertexBuffer.PositionNormal{
        Position = new Vector3(0,0,0)
    },
    new VertexBuffer.PositionNormal{
        Position = new Vector3(2,0,0)
    }
};

Yukarıdaki şekilde bir Vertex dizisi oluşturduk. Hatırlayalım; Vertex oluştururken, bunu VertexBuffer sınıfında tanımlanmış public structure’ ları kullanarak yapıyoruz demiştik. Sadece Position özelliklerini tanımlayıp bir Vertices(birden çok vertex e verilen ad) oluşturdum. Bu Executable Cell i çalıştırdığımda, workbook bana hücrenin çıktısını yani iki elemanlı VertexBuffer.PositionNormal dizisini aşağıda gösteriyor.

outpar

Sırada VertexBuffer nesnemizi oluşturmak var.Aşağıdaki şekilde bir VertexBuffer objesi oluşturyorum. SetSize ve SetData metodları ile değerlerimi set ediyorum.

var vertexBuffer = new VertexBuffer(Application.CurrentContext, false){
    Shadowed = true
};
vertexBuffer.SetSize((uint)vertices.Length, ElementMask.Position | ElementMask.Normal, false);
vertexBuffer.SetData(vertices);

Şimdi bu vertexbuffer’ ın ne şekilde birleşeceklerini söyleyeceğim nesenemi yani Geometry’ imi tanımlıyorum.

var geometry = new Geometry();
geometry.SetVertexBuffer(0, vertexBuffer);
geometry.SetDrawRange(PrimitiveType.LineList, 0, 0, 0, (uint)vertices.Length, true);

Sırada Model sınıfımı tanımlamak var. oluşturduğumuz geometry nesnelerini Model nesnesi ile bir araya getirebiliyorduk. BoundingBox propertysine set ettiğimiz değerlerin bu örnek için bir önemi yok, o yüzden biri orijinde diğeri (1,1,1) noktalarında iki Vector3 tanımladım.

var model = new Model();
model.NumGeometries = 1;
model.SetGeometry(0, 0, geometry);
model.BoundingBox = new BoundingBox(new Vector3(0,0,0), new Vector3(1,1,1));

Oluşturmuş olduğum bu Model objemin görselliği ile alakalı değerleri Material nesnesi ile set ediyoruz. Bu örnekte basitçe, bir desen kullanmadan sadece bir mavi renkten oluşan Material oluşturuyorum.

var material = Material.FromColor(Color.Blue);

Sonunda ekranda göstermek istediğim modelimi oluşturmuş oldum. Bunu Simple Application’ın benim için oluşturduğu RootNode’a yeni bir node ekleyerek, ekranda gösterme kısmınıda yapıp, artık bu mavi çizgimi oluşturduğum canvas’ta görmek istiyorum. Workbook’ta her bir executable cell, tekrar tekrar çalışabileceği için, oluşturacağım node’u önce RootNode’dan kaldırıyorum ki duplicate node’larım olmasın.

app.RootNode.RemoveChild(app.RootNode.GetChild("lineNode"));
var lineNode = app.RootNode.CreateChild("lineNode");

var line = lineNode.CreateComponent();
line.Model = model;
line.SetMaterial(material);

Veee sonunda canvas’ımızda da şekilde ki gibi bir mavi çizgi görüyoruz. outputurho

Bir sonraki yazımızda, biraz daha kod ağırlıklı bir örnek yapacağız. O zamana kadar bu temel terimleri anlamakta ve en temel anlamda kullanmakta fayda olacaktır.

Bu örnekte yapmış olduğum workbook dosyasını şuradan indirebilirsiniz.

Bir sonraki yazıda görüşmek üzere…

UrhoSharp’a Giriş

Herkese Merhaba,

Bu yazımda 29 Eylül 2017 Cuma akşamı Yiğit Özaksüt  ve Cihan Yakar ile gerçekleştirdiğimiz Xamarin Istanbul Development Meetup etkinliğinde anlattığım UrhoSharp’tan bahsedeceğim.

Meetup’taki sunumumu şuradan indirebilirsiniz.

Şimdi UrhoSharp konusuna gelelim. UrhoSharp, Urho3D adıyla hayata geçmiş ve başarılı bir 3D grafik ve oyun motoru olan Cross-Platform çalışabilen ve C++ API’a sahip projenin, tam olarak Xamarin ve diğer Microsoft ortamlarında çalışabilecek C# / .NET wrappers ile yeniden yazılmış halidir.

urho1

3D konusuna daha önceden hiç bulaşmamış olanlar için öncelikle UrhoSharp’ı kullanırken fazlaca kullanacağımız birkaç  terimden bahsetmek istiyorum.

  • Vertex / Vertices
  • VertexBuffer
  • Geometry
  • Model
  • Material
  • StaticModel
  • Node
  • Light
  • Camera
  • Scene

Bunların neler olduğundan bahsedelim. Boş uzaydaki tek bir noktayı düşünün, bu noktayı UrhoSharp’ta tanımlamak için kullandığımız nesne Vertex ama kendisini tam olarak bu isim ile değil de VertexBuffer nesnesi içine tanımlanmış public structure’lar olarak göreceğiz. Birazdan detaya ineceğim ama öncesinde, boş uzaydaki bu noktanın (yani Vertex in) sahip olduğu özelliklerden bahsetmek istiyorum. Hepinizin tahmin edeceği üzere olmazsa olmaz ilk özellik bu Vertex‘in uzaydaki koordinatı (Position). Bu özelliği UrhoSharp içerisinde yine bolca kullanacak olduğumuz Vector3 nesnesi ile belirtiyoruz. Bu Vector3 nesnesi bizden x, y ve z koordinatlarını isteyen constructure’a sahiptir. Mesela basit bir Vector3 nesnesini şu şekilde tanımlayabilirsiniz:

var coordinate = new Vector3(0,0,0);

(Bu kod ile 3D uzayda, tam orijinde duran,  x, y ve z değerleri 0 olan bir Vector3 tanımlamış olduk)

Vertex‘ in önemli 3 diğer özelliği daha vardır:

  1. Normal: Vertex’in bulunduğu yüzeye dik olan vektördür. Bu özellik öncelikle bize ışık ile etkileşime girme konusunda çok fayda sağlayacak.
  2. Color: Vertex in sahip olacağı renk.
  3. Texture: Vertex in bulunduğu yüzeyi kaplayacak olan dokunun, bu vertex için olan 2 boyutlu koordinatıdır. Vector2 ile tanımlıyor olacağız.

Boş uzayda tanımadığımız bu noktaları, bir araya getirmek için kullanacağımız nesnemiz ise VertexBuffer olacaktır. Yukarıda söylediğim gibi Vertex UrhoSharp’ta programatik olarak birşeyler çizebilmemiz için gerekli olan en küçük parça ama onu bu isimle görmeyeceğiz demiştim. İşte ilgili özellikleri ile bu vertex’i, VertexBuffer altındaki public structure’lar ile şu şekilde tanımlayabilirsiniz:

var VertexBuffer.PositionNormal = new VertexBuffer.PositionNormal {…}

var VertexBuffer.PositionNormalColor = new VertexBuffer.PositionNormalColor {…}

var VertexBuffer.PositionNormalColorTextcoord = new VertexBuffer.PositionNormalColorTextcoord {…}

Position özelliği dışında, diğer özelliklerini boş geçerek bir Vertex tanımlaması yapabilirsiniz. Bir de çokça duyacağınız Vertices adından bahsedeyim. Bu aslında birden fazla Vertex için duyacağınız isimdir yani bir üçgen oluşturmak için 3 adet Vertex tanımladınız diyelim, bu arkadaşları hep beraber çağırmak için Vertices adını kullanacaksınız, bilginiz olsun.

Peki, devam edelim. Noktaları oluşturdunuz ve VertexBuffer içinde bunları topladınız, bu noktaların ne şekilde birleşeceklerini nasıl söylüyoruz?

Geometry: Bu sınıfı aynı ismiyle UrhoSharp’ta yine çokça kullanmanız gerekecek. Geometry, bir veya birden fazla VertexBuffer nesnesinin ne şekilde birleşeceklerini ve nasıl yorumlanacaklarını söylemek için kullanacağımız bir nesnedir.

Vertices hazır, VertexBuffer’lar hazır, Geometry ‘er hazır. Tüm bunlardan sonra bu Geometry nesnelerini bir araya getirip bir görsel tanımlama işine bizi yaklaştıran önemli sınıflardan biri ise Model sınıfı olacak. Model sınıfı ile bir veya birden çok geometry objesini bir araya getirip bir model yaratmış olacağız. Bunu projemize önceden tanımlanmış haliyle, “.mdl” uzantılı dosya olarak ekleyebiliriz ya da programatik olarak bunu başarabiliriz.

Material: Oluşturduğumuz bu model nesnesinin, 3 boyutlu görselliği ile alakalı bileşenlerini Material nesnesi ile tanımlıyoruz. İstersek sadece bir renk verebiliriz (ki bu durumda Vertex’i tanımlarken verdiğimiz Color değerlerini ezmiş oluruz, ama ezmemenin de yolları var tabii.) istersek de bir bitmap vb şekilde yüzeyi kaplayacak olduğumuz dokuyu verebiliriz.

Bu Model  ve Material nesnelerini biraraya getirip, nihai bir görsellik sağlamak için kullancağımız sınıf ise StaticModel component’i olacaktır. Hazır Component demişken, hemen ondan da kısaca bahsedelim. Component nesnesi ile artık hali hazırda olan modelimizi hayata geçirebiliyoruz. Hayata geçirmekten kastım, öylece duran modellerimize, eklediğimiz Component’ler sayesinde, ses yaymalarını, fizik kurallarından etkilenmelerini ve birbirleri ile etkileşime geçmeleri gibi birçok özelliği vermek.

Peki artık modellerimiz hazır, belli componentler ile belli özellikler de aldılar peki bunları ekranda nasıl gösteriyor olacağız?

Son 3 önemli terimden bahsetmek istiyorum,

  1. Camera: 3D ekranımızda Camera nesnesi kendi görüş alanında kalan herşeyi bize gösteriyor olacak. Camera objesininde tabii ki, uzayda bir Position‘ı ışık yayma şekli ve bir görüş alanı olacaktır. Bu görüş alanını FOV (Field Of View) dediğimiz özelliği ile belirteceğiz. (Default hali 45 derecedir.)
  2. Light: UrhoSharp’ ta 3 tip ışık var. Bu ışıkları sahnemizi aydınlatmak ve tüm objelerimizin ne şekilde görüneceğini belirlemek için kullanıyoruz. Tam burada şunu söylemek isterim ki 3D Grafikte Curve (eğri) yüzey diye bir tanım yoktur aslında. Eğim olarak gördüğümüz şey, ışığın geliş şekli ve o yüzeyi oluşturan Vertices’in Normal vektörleri ile yaptıkları açıların etkileşiminden başka bir şey değildir.
    1. Directional: Belli bir yönden gelen ve o doğrultuda ilerleyen sonsuz ışındır. Güneş ışını gibi düşünebilirsiniz.
    2. Point: Belli bir noktadan gelen ve tüm doğrultularda yayılan ışındır. Bir ampulün yaydığı ışın olarak düşünebilirsiniz.
    3. Spot: Belli bir noktadan gelen ve belli bir doğrultuda görülecek ışındır. El feneri gibi düşünebilirsiniz.
  3. Scene: Tüm modellerimiz ve kamera ile ışık sayesinde oluşturduğumuz sahneyi temsil etmektedir.

Bu kadar fazla terimden bahsettikten sonra örnek yapmadan olmayacaktır tabii ki. Bir sonraki yazımda, tüm anlattıklarımı içeren, güzel örnekler ile karşınızda olacağım. O zamana kadar, bu terimleri sindirmenizi, UrhoSharp ile ilgili bulduğunuz yazıları okumanızı öneririm. Birkaç yardımcı link vermek isterim:

  • Xamarin.com da buradaki linkten başlayarak ilgili tüm UrhoSharp yazılarını okumanızı öneririm. UrhoSharp’ı Xamarin.Forms ile kullanabileceğimiz gibi, tabii ki Xamarin.iOS yada Xamarin.Android ile de kullanabiliriz. Hatta Xamarin dışındaki diğer Microsoft yazılım platformalarında da rahatça kullanabilirsiniz. En nihayetinde başarılı bir  C++ API ile yazılmış kütüphanenin C# ve .NET wrapper ile devşirilmiş halini kullanıyorsunuz.
  • Bu temelleri anlamadan biraz sert kaçar ama, geçenlerde Charles Petzold abimizin yaptığı webiner ı izlemenin de ilerideki aşamalarda faydası olacaktır. Kendisi kod ile mobiusstrip yaptı, izlemeye kesinlikle değer.