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 =)

Directx üzerinde md3 modelleri

Quake 3 te modeller için kullanılan md3 dosyalarını yüklemeye başladım. Hala biraz eksiği var o yüzden kaynak kodunu henüz veremeyeceğim.

leg1

Kontroller

v: tüm vücudu kapsayan animasyonları değiştiriyor (ölme animasyonları)
b: bacaklar için olan animasyonu değiştiriyor
n: göğüs animasyonunu değiştiriyor

link

Collision Detection Üzerine

Biraz internette bulduğum bir collision detection algoritması üzerine bahsedeceğim. Şu sitede tanıştım kendisi ile

http://spiritking.tripod.com/cdtut.htm

Algoritma hareket eden insanı bir silindir olarak düşünüyor. Mantık olarak çok güzel düşünülmüş, performansıda gayet iyi gibi duruyor. Lakin sitedeki implementation biraz kusurlu olmuş ve algoritmanın biraz eksiği var gibi.

Collision detection için gerekli olan verilerimiz, kamera koordinatı, silindirin alt ve üst sınırlarının y koordinatları ve bir de silindirimizin yarı çapı. Ayrıca polygonlarımızın koordinatları, normal leri lazım olacak.

Şu resmi bir inceleyelim. (Yukarıdaki sayfada olduğu gibi benim programımda da y ekseni yukarısı olarak tanımlanmış)

collision1

Yukarıdaki resimde 3 tane polygonumuz var. Kamerada silindir ile gösterilmiş. En sağdaki polygon silindir ile collision yapmış gibi duruyor (daha kolay anlaşılması için o üçgeni hafif eğimli bir duvar gibi düşünün bizde üzerine doğru yürümüşüz) Sahnenin z yönünde bir kesini görüyoruz. Collision detectionun ilk aşaması silindirin alt ve üst yüzeylerinden geçen 2 tane düzlem düşünün. Bütün polygonları bu iki düzlem arasında kalan kısımlarını kullanıyoruz. Mesela soldaki polygon un hem üstünden hem altından kesmişiz ve sonuçta silindirin yükseklik sınırlarında kalan bir beşgen ortaya çıkmış.  Ortadaki polygon tamamı iki düzlem arasında kalmış, o yüzden bir kesintiye uğramıyor. Sağdakininde sadece alt kısmı kesilmiş ve gene ortaya bir üçgen çıkmış.(eğer bir polygon bu iki düzlemin tamamen ters taraflarında ise tamamen göz ardı edilecekti)

Ortadaki resim sadece polygonların kesildikten sonraki halini gösteriyor. Görebileceğiniz gibi kestiğimiz kısımların collision yapabilmesi imkansızdı, sadece bu parçalar collision ihtimaline sahip.

Burada kesme işleminin nasıl olduğunu anlatayım. Verdiğim sitedeki örnekten biraz daha farklı bir yol izledim, oradaki örnek hatalı gibi geldi ve bazı durumları atlayabiliyordu.

Kesme işlemi alt ve üst sınır için iki kere yapılıyor. her abc üçgen için abc üçgeni için 3 tane doğru parçamız var, ab bc ca. Her doğru parçası için şu algoritmayı uyguluyoruz.

  • Eğer her iki noktada doğru tarafta ise, ikinci noktayı al.
  • Birinci nokta doğru, ikincisi yanlış tarafta ise doğru parçasının sınır ile kesiştiği yeri al.
  • Birinci nokta yanlış, ikincisi doğru tarafta ise önce doğru parçasının sınır ile kesiştiği yerisonra ikinci noktayı al.
  • Her iki noktada dışarda ise hiç bir nokta alma.

Bu algoritma sonucu aldığımız noktalar üçgenin plane in doğru tarafında kalan kısmı olmuş oluyor. Mesela yukarıdaki resimde soldaki üçgen için

collision21Önce üst kısım için clip yapıyoruz. a dan b ye giderken her iki noktada doğru tarafta, sadece b alınıyor. b den c ye giderken b içerde c dışarıda bc doğru parçası ile sınırın kesiştiği yeri (bc’) alıyoruz. c den tekrar a ya giderken ilk nokta yanlış ikincisi doğru yerde olduğu için kesişim noktasını (ca’) ve sonra a yı alıyorız. sonuçta yeni oluşan şekil. b bc’ ca’ a dörtgeni oluyor. aynı işlemi bu sefer alt sınır için yapıyoruz ve sonuçta bc’ ca’ a b(bc’)’ ab’ beşgenini elde etmiş oluyoruz. Bu algoritma sonucu elimizde en iyi ihtimalle 0 nokta  (tüm noktalar dışarıda ise) en kötü ihtimallede bir beşgen oluşacak.

En alttaki resim algoritmanın güzel tarafını gösteriyor. Bütün polygonları kestikten sonra bu sefer y ekseni yönünde bakam bir kesit aldığınızı düşünün. Her şey iki boyuta iniyor ve silindirimiz bir çembere dönüşüyor. Eğer bu çember içinde kalan bir polygonumuz varsa bu onun silindir içinde kaldığını ve kamera ile çarğıştığını gösteriyor!

Peki 2 boyutlu düzlemde bir çember ve doğru parçasının (artık şekilleri doğru parçası array i olarka düşünelim =) ) kesiştiğini nasıl anlayacağız? Bunun için biraz vektör bilgisine ihtiyaç var. Sitede verilen örnek programın bu kısmı düzgün çalışıyor, açıklamasına şuradan bakabilirsiniz.

http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/

Burada farklı olan tek şey eğer doğru üzerindeki nokta doğru parçası dışında ise biz o noktaya yakın olan sınırı alıyoruz.

Eğer çemberimiz şekil ile kesişiyorsa kişiyi hareket ettirmek durumunda kalıyoruz. Burada iki ihtimal var. Ya üçgenimizin üzerine tırmanırız (eğer eğim uygun ise) veya silindiri üçgen ile kesişmiycek şekilde uzaklaştırırız.

collision31İkinci durum daha kolay olayı, iki boyutta düşünürek halledebiliyoruz. Eğer aradaki uzaklık a ise, çemberi r – a kadar hareket ettiriyoruz ve sorun çözülüyor.

collision4Birinci durumda (verdiğim sitede yeterli anlatılmamış, eksik kalmış gibime geldi) ise işler biraz daha karışık. Eğer üçgenin eğimi uygun ise üçgenin üzerine tırmanmamız gerekiyor.  Öncelikle çemberin kesişen nokta yönündeki uç noktayı (a boktası) buluyoruz. Amaç bu a noktasını yeterince yukarı kaldırmak böylece collision u engellemek. Bunun içinde üçgen üzerinde olan a’ noktasını bulmak lazım. Bunu bulmak içinde şu formülü kullandım.

http://gpwiki.org/index.php/MathGem:Height_of_a_Point_in_a_Triangle

Bu linkte procedure kısmındaki formül ile a’ noktasını buluyoruz. Bu nokta üçgen üzerinde ve a ile aynı x-z koordinatlarına sahip (formülde z ve y harflerini değiştirin, bizim aradığımız y). a’ noktasını bulduktan sonraa ile arasındaki yükseklik farkını buluyoruz ve silindirimizi o uzunlukta yukarı kaldırıyoruz.

Bütün sorunları bu şekilde çözemiyoruz malesef. Bir diğer problem ise tamamen yatay düzlemlerde oluşuyor. Mesela yüksek bir noktadan düştüğümüzü düşünün. Altımızda ise büyük bir üçgen var, bu üçgen bizim silindirimizin sınırlarına girdiğinde üstten görünüş şu oluyor.

collision5Burada dikkat ederseniz hiç bir doğru parçası çember ile kesişmiyor, ama yine de bir collision var. Bu durumu anlayabilmek için bir test daha gerekiyor. Bu testte çemberin merkezinin üçgen içinde mi değil mi onu arıyoruz. Bunun için abc üçgeni ve n noktasında her doğru parçası için merkez aynı tarafta mı kontrol ediyoruz. mesela ab doğru parçası için önce an vektörünü buluyoruz ve bunun dot product ını hesaplıyoruz, aynı işlemi bc ve ca için de yapıyoruz. Eğer bütün dot product lar pozitif ise nokta çemberin içinde demek oluyor. Bu durumda yine aynı şekilde silindiri bir parça yukarı kaldırarak sorunu çözüyoruz. (şurada ayrıntı açıklama var http://www.blackpawn.com/texts/pointinpoly/default.html)

Ama maalesef bu da yeterli olmuyor =) Bir diğer (ve oldukça büyük bir sorun) ise eğer çok hızlı hareket ediyorsak ne olacağı. Bu durumu henüz programa eklemedim ama şu şekilde çözülebilir. Önceki koordinatımızdan yeni koordinata bir doğru parçası çizdiğimizde eğer bu doğru parçası polygon ile kesişiyorsa collision oluyor demektir. Ama bu tam yeterli bir çözüm değil o yüzden henüz eklemek istemedim. Aklıma daha iyi bir çözüm geldiğinde onu eklemeye çalışacağım.

Programın son hali

Kaynak dosyaları

(ek: f tuşunu basılı tutarak uçabiliyorsunuz =D)

Directx, ilk testler

Yavaş yavaş directx ile örnekleri incelemeye ve kendi çalışmalarımı yapmaya başladım.

Directx kullanırken aslında opengl i yanlış kullandığımı farkettim. Misal opengl de bir şekil çizerken

glVertex3f(…);
glVertex3f(…);
glVertex3f(…);

gibi 3 tane koordinat veriyordum. Bu fonksiyonlarda bu koordinatları ekran kartına yolluyor ve çizim işlemlerine başlıyordu. Her frame için tekrar tekrar yolladığımız için çok fazla yük biniyormuş.

Directx öğrenirken ise bu koordinatları (vertex leri diyeyim artık) bir vertex buffer ına bir kere yazıyoruz ve daha sonra bu buffer ı ekran kartı hafızasına kopyaladığımızı gördüm. Daha sonra istediğimiz zaman directx e “koordinatları bu bufferdan al artık” diyerek ekstra bir işlemci-ekran kartı arasında veri akışı olmadan çizimlerimizi yapabiliyorduk.

Yanlış hatırlamıyorsam opengl de de vardı böyle bir işlem (illa vardır yani =) ). Lakin bu özelliği kullanmayınca çok daha küçük polygon sayıları ile uğraşıyordum. Directx de ne kadar fazla polygon kullanabildiğimi görünce ufak bir şok yaşadım.

Bir örnek ile göstereyim. Aşağıda ki örnekte 512*512*2 yani yaklaşık 525 bin tane polygon var. Ve gayet akıcı bir şekilde çalışıyor.

test2test1

test3test4

Binary dosyalar
Kaynak Dosyalar

Shader değiştirmek için 1-9 tuşlarını kullanabilirsiniz.

Sol üst resim haritanın normal renkleri. Sağ üst resim ise siyah beyaz. Siyah beyaz olması için pixel shader kullandım. Kabaca pixel shader her pixel ekrana çizilirken ekran kartı üzerinde çalışan o pixelin rengini veren program(cık). Mesela ilk resim için pixel shader o an kullandığımız texture üzerinde gerçek rengi döndürürken, siyah beyaz yapabilmek için (r + g + b)/3 rengini döndürüyoruz. Pixel shader HLSL ile yazılıyor, ve .fx dosyaları içinde bulabilirsiniz.

Sol alt resim gene farklı bir pixel shader ürünü. O anki görüntünün emboss effect li halini veriyor. Son resim için durum biraz daha farklı. O post processing ile yapıldı (aslında hepsi post processing ile yapılı benim örneğimde ama son resim için post processing zorunlu =)). Postprocessing sahnenin ekrana değilde bir buffer a çizilmesi ve daha sonra bu buffer ekrana çizilirken pixel shader ile oynamalar yapılması işlemi. Burada da resmin x koordinatının sinüs üne göre y koordinatını hafif kaydırıyoruz ve böyle dalgalı bir görüntü elde etmiş oluyoruz.

Ayrıca dikkat ederseniz t3.x diye hayvani boyutta bir dosya var. Bu arazinin model dosyası. 3d max ile oluşturdum. İşleri baya basitleştiriyor, .x dosyasını yükledikten sonra tek bir fonksiyon çağırarak kendisini çizebiliyoruz. Lakin çizmek dışında pek bir işlemimiz yok tabi. Mesela collision detection yapabilmek için .x dosyasını yüklüyorum, daha sonra bunu tekrar normal ram e kopyalıyorum anca o zaman kullanabiliyorum =)

Bu ara pek haşır neşir olduğum siteler

http://www.directxtutorial.com/ başlangıç için harika bir kaynak
http://www.applicachia.com/ çok güzel örnekler var. Benim örnekte aslında buradakilerden bir tanesinin üzerinden gidiyor =D

ve google tabiki =)

Daha yazılacak çok şey var ama aklıma gelenler bunlar. Geliştirdikçe daha ayrıntı olarak anlatacağım umarım

Opengl’den Directx’e geçiş dönemi

Gerçekten sancılı bir dönemmiş. Henüz directx e yeni başladım ve opengl den ne kadar çok farklı olduğu görülebiliyor.

En başta glut tarzı bir çok işi basitleştiren bir arayüzün (bir adı vardı ama unuttum şimdi) yokluğu hissettiriyor. Bir pencere açabilmek ve bunu opengl e bağlamak glut ile hazır fonksiyonlar ile yapılırken directx de her şeyi biz yapıyoruz. Tabi bu çok daha fazla esneklik sağlıyor ve daha iyi öğrenmemize yarıyor ama en basit uygulamalar için bile fazladan ~200 satır kod anlamına geliyor. Çoğunlukla copy paste olsa da okunabilirliği feci oranda düşürüyor. Aslında bir ara bunları basitleştirecek bir kütüphane yazmak geliyor içimden ama ondan önce öğrenecek çok şey var.

Bir diğer sıkıntı da opengl de tek bir fonksiyonla yaptığımız şeylerin directx de çok uzun sürmesi. Mesela glRotatef yerine şöyle bir şey diyoruz.

[code language='c++']

D3DXMATRIX matRotateY;
D3DXMatrixRotationY(&matRotateY, index);
d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY));
[/code]

Bizleri düşünen birisi bunun için hazır bir kütüphane yazmış, çok hoş duruyor ama henüz kullanma fırsatım olmadı.

http://www.adamdawes.com/programming/windows/directx_matrixtransforms.html

Bir diğer zorluk da bana sanki directx için daha az kaynak var gibi geliyor. opengl de herhangibir konuda bir yığın örnek bulunabilirken directx’de bu durum daha sıkıntılı gibi.

Directx te şu an en çok ilgilendiğim konu shader lar. Basitçe tanımlamak gerekirse shader dediğimiz GPU üzerinde çalışabilecek programcının yazdığı uygulamalar. 3 çeşidi var: vertex shader, pixel shader ve geometry shader.

c++ dan farklı bir dil HLSL: ile yazılıyor. Açılımı High Level Shading Language ama gözüme o kadar da ‘high’ gelmedi. Ama bir diğer seçenek olarak assembly ile de yazılabiliyor ki buna göre tabi çok daha yüksek seviye kalıyor tabi =)

Şurada shader lar için basit bir kaç örnek var (ayrıca oyunu da oynayın muhteşem yapmış adam)

http://www.facewound.com/tutorials/shader1/

Öğrendikçe daha ayrıntılı bilgiler vermeye çalışacağım, kendime iyice kavramak için bir yaz süre vardım, fazla bir sayılır ama yazın sıcağında pek heves kalmıyor =)

Game of Life! (msw logo üzerinde ^^)

Okulumuzun ilk döneminde bize öğretilen program idi msw logo. Yeni öğrenciler programlamaya giriş yapsın diye bu tip eğitim programları gösteriliyor.

Msw logo bir çizim programı denebilir, fakat kullanıcılar komut girerek çizim yapıyorlar.

logo2

Yukarıdaki üçgen (ismi turtle, eskiden hakikaten kaplumbağa şeklindeymiş ondan adı böyle =)) bizim kalemiz. Biz verdiğimiz komutlarla turtle ı hareket ettiriyor, döndürüyor ve çizim yapıyoruz. Yukarıdaki örnekte turtle karenin sol alt köşesinden başladı ve yukarı bakıyordu. fd 100 (forward 100) ile 100 pixel ileri gitti ve karenin sol kenarını çizdi. rt 90 üçgeni 90 derece saat yönünde döndürdü. Sonra gene fd 100 ile karenin üst kenarını çizdik. Yukarıdaki komutları takip ederek resimdeki şekli oluşturduk.

Kulağa komik bir program gibi gelebilir =), ama gayet geniş bir şey aslında. 3d çizim yapmaya izin veriyor mesela. İnternette araştırılırsa çok güzel çizimler sunan basit kodlar bulunabilir. Mesela bir örnek şu (tıklayarak büyük halini açın):

desen

Bu deseni ortaya çıkartan kod da şurada. Denemek için Edall a tıklayın, kodu yapıştırın, “save and exit” ile çıkın ve komut verilen yere “db 2 6” yazıp çalıştırın. Yapan arkadaş recursive in dibine vurmuş hakikaten.

Benimde yıllar sonra aklıma esti ve game of life ı msw logo üzerinde çalıştırayım dedim =D. Sonucu da burada

gameoflifemswlogo

Kaynak kodumuzda buradan alabilirsiniz.

http://www.shultays.com/gameoflifelogo.txt

Kullanmak için Edall butonuna tıklayın, açılan pencereye bu kodu yapıştırın ve “save and quit” ile pencereyi kapatın. Daha sonra komut yerine “gameoflife 16 16 100” yazarak game of life ı başlatabilirsiniz (ilk 16 değeri satır sayısı, ikinci 16 sütun ve 100 de toplam kaç generation yapılacak onun sayısı, isteğinize göre arttırıp azaltabilirsiniz)

Mswlogo yu indirebilmek için.

http://www.softronix.com/logo.html

Game of Life hakkında bilgi

http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

Now you are thinking with portals

Stencil buffer’ın ne olduğunu öğrenmem ve sonrasında “Portal yapılır bunla” fikrinin gelmesi ile başlayan proje.

Portal nedir diyenler için herkesin denemesini tavsiye edeceğim Valve’nin ürettiği bir oyun. Amaç oluşturduğumuz portallar yardımıyla başlangıç noktasından bitiş noktasına gitmek.

Peki “portal” nedir derseniz, şöyleki: iki tane kapı hayal edin, birinden girdiğimiz de aslında diğerinden çıkıyoruz. Türkçe de kurt deliği diye kullanılıyor (hoş aslında oda wormhole ya neyse) diye düşünüyorum.

Yani bir ss ile anlatmak gerekirse:

port11portal21

Bu dikdörtgen pencere gibi duranlar portallarımız oluyor, pembe renkli şekil sarı duvardaki portalın önünde, dikkat ederseniz kırmızı duvardaki portaldan baktığımızda hemen önde onu görüyoruz.

Daha iyi anlamak için programı deneyin =)

İki sürümü var, hemen hemen aynı. Başta windows ta yazmıştım, daha sonra linux üzerinde test ettim.

Windows sürümü için glut isimli kütüphaneyi kullanmanız gerekiyor. Kendisinin asıl amacı opengl komutlarını bir parça basitleştirmek ve opengl i platformdan bağımsız olarak çalıştırmak. Ama klavye fonksiyonları çok zayıf olduğu için windows.h kütüphanesinden bir fonksiyon kullanmak zorunda kaldım. Bu yüzdende linux sürümünde glfw diye glut yerine başka bir kütüphane kullandım.

glut hakında bilgi için
http://www.opengl.org/resources/libraries/glut/
glfw hakkında bilgi için
http://glfw.sourceforge.net/

glut sürümünde linker a glut opengl ve glu kütüphanelerini vermelisiniz. glfw için biraz daha fazla şu kütüphaneler lazım olaca: glfw, GLU, GL, X11, pthread, Xxf86m, m, Xrandr. Ayrıcı -L ile şu klasörüde vermelisiniz: /usr/X11R6/lib

Programı yazarken hiç comment yapmamıştım =) Şu an biraz eklesem de hala kaynak kodu açık olmaktan çok uzak. Şu an saat sabah 7 ve uykusuzluk sayesinde hiç şevkim kalmadı doğrusu =D İlerde projeyi geliştirmeye başlarsam daha açık bir şekilde anlatmayı düşünüyorum.

Çalıştırabilir dosyalar

Windows
Linux

Kaynak kodları (windows visual c++ da hazırlandı, direk olarak dsp dosyasını açabilirsiniz. linux eclipse ile hazırlandı. c eklentisini kurduktan sonra workspace ine atın)

Windows

Linux