Boş vakit 2

[sourcecode language=”cpp”]include <stdio.h>
int main(){
char t[] = "èfİ÷¬—}ÖJÕwÓÕ|t³İï"γû¤ÛÖ²¯²ì¡ú®×ÖšïE›­û\0\0\0";
unsigned *a= (unsigned*)t, y=0;
do printf("%c", ((y=y*((*a)&1)+1)-1)?(y>5)?10:32:10+32);
while(*(((*a>>=1)-1)?a:++a));

return 0;
}[/sourcecode]

cse 112 labwork 1 in cevabı

Stonehenge

Burayı görme fırsatı da yakalamış olduk

Lakin malesef taşlara pek yaklaştırmıyorlar, uzaktan izliyorsun öyle. Baya fazla hırpalanmış sanırım, bu yıldan itibaren yakınına gidemiyormuşuz. Doğrusu biraz hayal kırıklığı yaşattı, yakından görmeyi gerçekten çok istiyordum.


Buda bayadır göremediğim bir sahne. Resimde seçemeyenler için bu bir gök kuşağı 🙂

Roma zamanında kalma bir şehirmiş. Adındanda anlaşılacağı banyoları ile meşhur 🙂 Şehirde bir çok halka açık banyolar bulunuyor, fakat malesef gezide test etme imkanımız yoktu. Başka bir bahara artık

Geocities

Acımız büyük, bu gün geocities kapanıyor. Kapanmadan önce bir bakayım nelerim varmış diye 5 yıl önceki çalışmaları mı görüp hüzünlendim =) Ama maalesef bir çoğu 7host’ta duruyordu fakat 7host kullanmıyorum diye hesabımı silmiş =(

misal şu resme tıklayıp 4 yıl öncesinden bir oyun görün.

erman

Sağ sol yukarı ve boşluk tuşları ile oynanıyor. Amaç mümkün olduğu kadar adam öldürmek =)

Bu da UO vaktinden kalma bi resim

tlmcikler

Bu gemiyi bir şekilde çalmıştık 😀 sanırım birisi anahtarı (veya her ne ile kontrol ediliyorsa) üzerine unutmuştu anında atlayıp götürmüştüm 😀 Sonrada lorac ben ve raistlin balık tutmaya gitmişiz ve gemide biraz uzanıyoruz (ayrıca ata dikkatinizi çekerim =D)

Düşünüyorum da bu UO’da pk lar ve diğerleri bir birine girmişken, ortalıkda katliam oluyorken biz üçümüz milletten bandajdır iksir malzemesidir çalmaya çalışırken aldığım zevki başka bir oyunda almamışım. Hey gidi günler hey

Bir küçük açıp geocities ile karşılıklı içesim geldi.

Geocities’in kapanışı üzerine xkcd.com un yaptığı bir tasarım var ki gözlerimden yaş getirdi. İlerde kapanabileceği ihtimali üzerine şuradan da ulaşabilirsiniz.

In These Stones Horizons Sing

Wales gezisinde gördüğümüz gayet ihtişamlı bir binada yazan söz bu.

Daha doğrusu yazılış şekli şöyle

in_these_stones_wmc

Crew Gwir In These Stones
Fel Gwydir Horizons
O Ffwrnais Awen Sing

Yarı ingilizce yarı welsh dilinde yazılmış. Wales’te bu iki dil de konuşuyormuş (ama sanırım gençler arasında artık welsh pek fazla tutulmuyor). Tabi bu şekilde karışık olunca gittiğimizde çözememiştik =) Sonradan Erhan araştırdı ve ne anlama geldiğini öğrendik. Welsh dilinde yazılan kısmın ingilizce çevirisi de şuymuş “Creating truth like glass from the furnace of inspiration” veya türkçe çevirisi “İlham fırınında cam yapar gibi gerçeği oluşturmak”

Neyse, işin özü ilginç bir mekan. Cardiff kalesi görülmeye değer bir yer.

Geziden bir kaç hatıra.

dsc00839dsc00922

dsc00903

dsc00839

dsc00871

dsc00870

Directx md3Loader

Uzun bir aradan sonra md3Loader ı tamamlamaya zaman ayırabildim.

md3

İki tane kütüphanemiz var. md3Model.h ve PlayerModel.h

md3Model.h .md3 dosyalarını projemizde kullanabilmemize yarıyor. load methodu ile bir texture ve md3 dosyası veriyoruz ve her şeyi kendisi hazırlıyor. Daha sonra draw methodu ile çizebiliyoruz.

Diğer kütüphanemizde PlayerModel.h. Bu kütüphane bir txt dosyasından gerekli adresleri alıyor ve modelimizi oluşturuyor. Yine aynı şekilde load ve draw methodu var. Fakat bunun draw methoduna bütün değişkenleri zor olacağı için değişkenleri hep public olarak tanımladım. Bunları düzenleyip draw methodunu çağırıyoruz. Umuyorum ki örnek programı inceleyince daha anlaşılır olacaktır.

Örnek dosya ve kaynak kodu

Biraz md3 dosyası yapısı üzerine bahsedeyim. Öncelikle şu sayfayı incelemekte fayda var. Bir md3 dosyası bir yığın structure ın birleşiminden oluşuyor.

En başta (adres 0 dan başlayarak) ana struct ımız bulunuyor. Bu structure da kaç toplam animasyonun kaç frame den oluştuğu, modelimiz içinde kaç tane surface (model parçacığı diyelim, mesela bir kafa modeli için kafa ve gözlük farklı surface ler olabiliyor) ve taglarımız sayısını bulabiliyoruz. (Ayrıca shader sayısı var ama ben kullanmadım)

md3 modelleri animasyon için frame diye bir yapı kullanıyor. Bir frame de model deki tüm noktaların o an ki koordinatı bulunuyor. Mesela sadece bir noktadan oluşan bir model düşünelim. Bu model 3 frame e sahip olsun ve animasyonuda sadece ileri gitmek olsun. Bu durumuda ilk frame de koordinatı 0,0,0 ikincide koordinatı 1,0,0 ve son frame de de 2,0,0 olacak.

Bir animasyonu oynatmak için sırası ile bu frame leri çiziyoruz. Mesela koşma animasyonu için toplam 10 tane frame bulunabiliyor. Ama aslında bu animasyon 2 saniye sürmesi gerekiyor. Eğer biz bu 10 frame i 2 saniyeye bölersek saniyede 5 frame göstermiş olacağız bu da akıcı bir hareket sağlamayacak.

Bunu çözmek için interpolation diye bir method kullanılıyor. Interpolation methodu 2 ana frame arasında geçiş frameleri oluşturmamızı sağlıyor. Bu geçiş frame i model üzerinde ki her noktanın linear interpolation u ile oluşturuluyor. Önceden verdiğimiz nokta örneği için frame 2.4 ü hesaplamaya çalışırsak 2. ve 3. keyframe leri kullanacağız. 2. keyframe deki koordinat 0.6 ile çarpılacak 3. frame de koordinat 0.4 ile çarpılacak ve toplamı bizim yeni koordinatımız olacak.

Özetle animasyonu olayı bu şekilde oluyor. Şunu belirteyim ki sitede belirtilen frame yapısında bahsettiğim koordinatlar tutulmuyor. Bütün koordinatlar surface yapısında tutuluyor. Frame de o frame için bounding box ve sphere tutuluyor.

Surface yapısına gelirsek asıl önemli her şeyin olduğı yapımız bu. Surface sayısı dediğim gibi bir modelde kaç tane modelcik olacağını gösteriyor. Genelde bu sayı 1 olsa da karışık modeller için daha fazla olabiliyor.

Bir surface yapısı özetle her nokta için koordinatlar ve UV değeri ve her üçgen için indice lerden oluşuyor. Toplam koordinat sayısı (modelimizdeki nokta sayısı)*(frame sayısı). Ayrıca her nokta için 1 adet UV yapısı (texture dosyasının hangi koordinatına denk geldiği) bulunuyor. Ve son olarak toplam üçgen sayısı ve her üçgen için hangi noktaların kullanıldığını gösteren bir yapımız bulunuyor.

Surface yapısı karışık bir yapı, ama bahsettiğim site gayet güzel bir şekilde anlatmış nasıl bir şey olduğunu orayı inceleyerek daha iyi anlayabilirsiniz.

Ve son olarak ta tag yapımız var (ana strucutre a bağlı). Tag yapısı o anki md3 dosyamızın diğer md3 dosyaları ile nasıl birleştirileceğini tutuyor. Mesela bacaklar için kullanılan bir md3 dosyasında tag_torso isminde bir tak bulunuyor. Bu tag ı kullanarak vücudun üst kısmını hareket ettirip yerine oturtabiliyoruz. Yine bu yapı her frame için farklı oluyor.

Daha ayrıntılı olarak anlatamayacağım malesef, ama dosyayı kullanmak istiyorsunuz sadece animasyonun nasıl olduğunu bilmeniz yeterli onuda örnek programı inceleyerek çözebilirsiniz zate. Kolay gelsin =)

Büyük sayılar üzerinde 4 işlem

Nerdeyse 3 haftadır Nottingham’dayım. Mutluyum. Yazamıyorum =)

Genelde bütün boş zamanımı bu directx projesi yiyor. Ama dün ve önceki gün zaman ayırıp (aslında inada girip =D) integer sınırlarını taşacak sayılar üzerinde işlem yapmayı sağlayan bir kütüphane yazabildim. Neden böyle bir şey yaptın diye sorarsanız bir şey diyemem =)

Kullanımı basit, operator overloading eklemeyi denedim çalışıyor gibi. Ama ilk defa böyle bir şey yaptığım için ne kadar doğru bilmiyorum.

Nasıl çalıştığına gelince, sayıları bir karakter arrayi olarak tutuyor. Array in her elemanını bir basamak olarak düşünelim, yani 256 lık taban üzerinde çalışıyoruz 😀

Mesela toplama yapmak için

a b c d
e f g h +
———
1 2 3 4

önce sondan başlıyor, d+h i buluyor ve bir integer a atıyor. sonra bu integer ın son 8 bit ini (int&0xFF) sonuçta 4 numaralı byte a yazıyor. daha sonra bunu sağa 8bit shift ediyor ve kalanı bir sonraki basamağın toplanmasında kullanıyor. kalan bu durumda zaten en fazla 1 olabilir. sonra aynı işlemi cg bf ae için yapıyor ve sonucu buluyor.

çarpma işlemi biraz daha karışık. önce h ile d den başlayıp a b c d ile tek tek çarpıyor. yine aynı şekilde kalanı bir sonraki basamağa atıyor (bu sefer kalan 1 den fazla olabilir). sonra aynı şekilde g ile a b c d yi çarpıyor ve sonuca ekliyor. böyle giderek sonucu hesaplıyor.

bölme işlemi ise en zoru =D

a b c d
e

önce böleni aynı hizaya gelecek şekilde kaydırıyor

a b c d
e 0 0 0

eğer ilk sayı diğerinde büyük ise sayıyı çıkarıyor ve sonuçta o kısma gelen bit i 1 yapıyor. daha sonra e sayısı sağa 1 kez shift ediyor (tüm sayıyı, yani hex olarak 0x2F 00 00 00 ise sayı shift edince 0x17 80 00 00 oluyor) ve aynı işlemi tekrarlıyor. sonuçta bölümden geriye kalan sayı kalan oluyor ve sonuçta elde ettiğimizde bölüm oluyor.

kodumuz ve örnek program burada

Eklenecek daha çok şey var, integer sayılarını toplayabilme çıkarabilme desteği, onluk tabanda bastırabilme desteği vs… Aslında hepsini tasarladım ama koda dökmeye üşeniyorum. Kim bilir belki bi gün =)

Aslında Odtü yarışmasında beri aklımda idi bu proje, o zaman bu tip bir sistem yapmıştım ama o hexadecimal olarak değilde 10luk tabanda çalışıyordu o yüzden çok daha az performanslı idi ve ayrıca bölme işlemi yoktu =)

2 ilginç olay

Uzun süredir yazamıyorum, tatil gibi bir şey yaptık bu gün bitti.

Bu gün iki tane ilginç şey öğrendim.

Birincisi integer (ve benzer 1 byte dan büyük değişken tipleri) hafıza da ters tutuluyormuş. Mesela integer 4 byte ise

[sourcecode=”cpp”]
int a = 0x04030201;
char *c = (char*)&a;
printf(“%d %d %d %dn”, *c, *(c+1), *(c+2), *(c+3));
[/sourcecode]

ekrana 1 2 3 4 basıyor. Yani a integer’ı hafıza 04 03 02 01 olarak değil de 01 02 03 04 diye tutuluyormuş. Niye böyle bir şeye gerek duydular bilmiyorum.

Bir diğer şey ise her data tipi her adrese yazılamayabiliyormuş. Mesela 4 byte olan bir integer sadece 4 ve katı olan adreslerde olabiliyor, 2 byte olan short ise sadece 2 ve katına konulabiliyor, 1 byte char ise her adreste olabiliyor.

Mesela bir structure oluşturursak

struct test{
char a;
int b;
char c;
};

bu structure adres 0x1000 de allocate edilirse o adresteki şu şekilde oluyor

a***bbbbc***

ilk önce byte olan a koyuluyor, ama ondan sonra b konulamıyor çünkü 4 ve katı adrese denk gelmiyor, 3 tane boş byte bırakılıyor ve sonra 4 bytelık b integer ı geliyor. daha sonra c geliyor ve ondan sonraki 3 byte gene kullanılamıyor.

ve sonuçta bu structure hafıza’da 12 byte kaplıyor. Eğer biz şu şekilde değiştirirsek

struct test{
char a;
char c;
int b;
};

bu sefer hafızada tutulan yapı şöyle oluyor.

ac**bbbb

ve toplam 8 byte lık yer kaplıyor.

Bu compiler a bağlı bir durum tabi. Akıllı compiler lar structure ları ikincisi gibi düzenleyebiliyormuş, fakat dev cpp bu konuyu atlamış gibi =) Bu olayın ismi struct padding miş.

Adreslendirme de bu şekilde bir zorunluluk yok, niye compiler lar böyle bir şey yapıyor bilemiyorum, eğer kodumuzun başına
#pragma pack(1)
yazarsak compiler bu olayı iptal ediyor ve bizim yazdığımız sırada ve gerçek boyutlarında hazırlıyor structure ları. Ama bir kötü yanı var ki kullanılıyor demek (belki de her mimaride çalışmıyordur)

Left4Dead tarzı Glow efekti

Oynamış olanlar neden bahsettiğimi biliyordur herhalde, oynamamışlarda kesinlikle denemesini öneririm.

Buradaki glow efektini directx üzerinde shader kullanarak yapmaya karar vermiştim. Sonuç yeterli gibi oldu.

test

Kullanması oldukça kolay. Kütüphanemizi yüklüyoruz. Effect i hazırlamak icin
void setupEffect(LPDIRECT3DDEVICE9 d3ddev, int w, int h);
fonksiyonu cağırılıyor. w ve h ekran boyutları oluyor.

Daha sonradan da
void drawGlowMesh(ID3DXMesh* mesh, D3DXVECTOR3 color);
ile mesh i color ile ekrana çiziyoruz.

Kullanabilmek icin bir kac seye ihtiyacımız var. d3ddev olusturulurken back buffer boyutlarını vermek zorundayız.
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.BackBufferWidth = SCREEN_WIDTH;

Ayrıca stencil buffer destekleyen bir depth&stencil format kullanmalıyız. En çok kullanılan D3DFMT_D24S8 sanırım.

Son olarakta alpha blending açık olmalı.

.h ve .fx dosyamız

Ayrıca şu linkteki örnek üzerine ekledim. main.cpp örnek teki kod. kendi eklediğim ve değiştirdiğim satırlar //*** ile comment lendi ve açıklama yazıldı.

Örnek program (Adı postprocess olduğuna bakmayın, üşendim şimdi düzeltmeye =))