![](images/logo.gif)
OpenGL ile Doku Sıkıştırma
Dokular (textures) 3 boyutlu uygulamalarda kaplandıkları yüzeye ayrıntı
vermek için kullanılırlar. Doku kullanımı ile az poligon sayısına sahip
bir modele daha gerçekçi bir görünüm verilebiliyor, dahası normal
mapping, bump mapping, specular mapping gibi gelişmiş doku kullanım
yöntemleri ile günümüzde bu ayrıntı verme işi oldukça ilerlemiş
durumda. Her geçen gün yarattığımız 3 boyutlu dünyalar gerçek hayata
yaklaşıyor. Gerçekçilik hissini arttırmak için daha fazla poligon, daha
yüksek çözünürlüklü dokular, çok daha fazla doku katmanının beraber
kullanımı gibi yöntemlere başvuruluyor. Quake2 zamannda 256x256 olan
doku çözünürlüğü yeterli görülürken günümüzde bu çözünürlük en alt
seviyelerden birisi olarak kabul ediliyor. Oyunlarda 1024x1024 gibi
çözünürlükteki dokuları kullanmak artık standart hale gelmeye başladı
bile. Normal map, bump map, specular map, gloss map gibi yüzey
gerçekçilik etkisini arttırıcı algoritmalarda kullanılan dokuların da
işin içine girmesi ile oyunlarda kullanılan toplam doku miktarı da
devasa boyutlara ulaştı.
Donanım üreticileri de tabiki boş durmadılar ve devamlı olarak doku
belleğini arttırmaya, ana bellek ile ekran kartı belleği arasındaki
yolların hızını ve efektifliğini arttırıcı yöntemleri ve ürünleri
piyasaya sürmeye devam ettiler. Günümüzde 256 MB belleğe sahip ekran
kartları yok satarken, 512MB belleğe sahip üst modeller piyasada
yerlerini aldılar bile. AGP veriyolunun devamlı hızlanması bir yana,
PCI Express standardı ile çok daha fazla ve bu defa her iki yönde de
çok daha hızlı bir veriyolu elde edildi. Tüm bu donanımsal gelişmelerin
yanı sıra yazılımsal olarakta bu gelişmeleri tamamlayan algoritmalar
ortaya çıktı. Doku sıkıştırma teknolojisi de işte tam bu noktada
önemini gösteren bir yazılım ve donanım yöntemi olarak karşımıza
çıkıyor.
Çoğumuzun uygulamalarında kullandığı doku dosyaları diskte
sıkıştırılmış bir resim formattında (*.png, *.jpg gibi..) ya da
sıkıştırmaya izin vermeyen bir formatta bulunurlar (*.bmp , ve
sıkıştırılmadan kullanılan *.tga gibi..).. Bu dokuları kullanmadan önce
diskten ana belleğe yüklemek, sıkıştırılmış ise algoritmik olarak ana
bellekte açmak (genelde yardımcı resim yükleme kütüphanelerini
kullanarak, örn: devIl, libpng, sdl_image) ve daha sonra opengl
fonksiyonlarını kullanarak ekran kartının belleğine yüklemek gerekir.
Diskte sıkıştırılmış olarak bulunan dosyalar ekran kartının belleğinde
ne yazık ki diskte kapladıkları kadar az yer kaplamazlar. Örneğin
1024*1024 çözünürlüğünde ve 32 bit renk derinliğine sahip bir doku,
ekran kartının belleğinde 4Mb kadar yer kaplar. Özellikle standart hale
gelen mipmap kullanımı ile bellek tüketimi 4Mb nin de üzerinde
olmaktadır. Doku sıkıştırma teknolojisinde ise dokular ekran kartı
belleğinde algoritmik olarak sıkıştırılmış bir formda tutulurlar, ve
ihtiyaç olduğunda kolaylıkla sıkıştırılmamış dokular kadar rahat bir
şekilde (bu işe özgü çipler sağolsun..) ve hızlıca kullanılabilirler.
Böylelikle devasa boyutta bir bellek kazancı elde edilmiş olur. Aşağıda
maddeler halinde sıkıştırılmış doku kullanmanın faydalarını sıraladım:
- Doku yükleme aşamasında diskten ana belleğe doku yükleme süresi
azalır. Diskte sıkıştırılmış halde bulunan dokular sıkıştırılmamış
resim formatındaki dokulara göre (*.bmp gibi) diskte çok daha az yer
kapladıkları için yüklenme süreleri azdır. Ayrıca sıkıştırılmış
dokuları grafik kartına göndermeden önce sıkıştırılmış resim
dosyalarını (*.jpg, *.png gibi..) ana bellekte açma gibi algoritmik bir
işlem yapılmadığı için işleyici zamanında da kazanım sağlanmış olur.
- Sıkıştırılmış dokular daha az yer kapladıkları için ana bellekten
ihtiyaç duyulduğunda grafik kartının belleğine yüklenme süreleri
azdır. Sıkıştırılmış doku kullanımı ana bellek ile doku belleği
arasındaki veriyolunun verimi arttırır.
- Sıkıştırılmış dokular çok daha az doku belleği kullanırlar.
Bu kadar faydalı özellik yanında sıkıştırılmış doku kullanmanın ufak
bir istenmeyen etkiside bulunmakta. Dokuları sıkıştırmakta kullanılan
algoritmalar genel olarak bir miktar doku kalitesinde eksilmeye yol
açarlar. Çoğu durumda bu kalite eksikliği göz ardı edilebilir oranlarda
kalmaktadır. Ama yine de en iyisi iki gerçekleştirimide uygulamaya
koyup aradaki farkı eksi ve artıları ile karşılaştırmak. [ Bu ]
sayfada çeşitli doku sıkıştırma algoritmalarının nVidia donanımında
hangi koşullarda nasıl çıktı verdiğine dair güzel bir resimli
karşılaştırma var. Ayrıca [ bu ]
sayfada da nvidia ve atı donanımlarının sıkıştırma sonuçları
karşılaştırılıyor.
Günümüzde neredeyse tüm oyunlar doku sıkıştırmayı bir şekilde
kullanıyorlar. Peki biz opengl programlarımızda bu faydalı özelliği
nasıl kullanabiliriz. OpenGL 1.2.1 sürümü ile beraber doku sıkıştırma
ve sıkıştırılmış dokuları ekran kartına yüklemeye yarayan
fonksiyonellik ARB onaylı olarak OpenGL içerisine alındı. Bugün NVidia
ve ATI nin ekran kartları ve sürücüleri doku sıkıştırmayı opengl
altında desteklemektedirler. GL_ARB_texture_compression ve
GL_EXT_texture_compression_s3tc eklentilerini kullanarak doku
sıkıştırma fonksiyonelliğine erişebiliyoruz. Uygulamalarımızda 2
şekilde doku sıkıştırmadan faydalanabiliriz. Çalışma zamanında doku
sıkıştırma ve önceden sıkıştırılmış dokuları kullanma.
Çalışma Zamanında Doku Sıkıştırma:
Bu kullanım şeklinde diskte bulunan resim dosyalarını eskisi gibi
belleğe çekiyoruz. Sıkıştırılmış bir format kullanıyorsak (jpg gibi)
bellekte sıkıştırılmamış pixel verilerini elde ediyoruz (bu işi jpeg
yükleme kütüphanesi yapacaktır). Daha sonra gluBuild2dMipmaps
fonksiyonunu yine eskisi gibi kullanıyoruz, fakat bu sefer kullanımda
tek bir parametre fark edecek. 2. parametre olan format parametresine
GL_COMPRESSED_RGB_ARB ya da 32 bit texture lar kullanıyorak (alpha
kanalı olan texture lar - *.tga gibi..) GL_COMPRESSED_RGBA_ARB değerini
vermemiz gerekiyor. Sadece bir parametrenin ismini değiştirerek
dokularımızın ekran kartına sıkıştırılmış olarak gönderilmesini ve
böyle işlem görmesini sağlamış oluyoruz. Ekran kartı sürücüsü uygun
gördüğü sıkıştırma algoritmasını bizim yerimize seçiyor ve kullanıyor.
Önceden sıkıştırılmış dokuları (dds) kullanma:
Bu kullanım şekli ile diskte daha önceden sıkıştırılmış şekilde bulunan
dokular direk olarak OpenGL eklenti fonksiyonları kullanılarak grafik
kartına gönderilir. Günümüzde sıkıştırılmış dokuları diskte tutmak için
yaygın olarak DDS formatı kullanılmaktadır. Bende bu yaygın kullanımdan
ötürü verdiğim örnekte dds formatındaki bir sıkıştırılmış dokuyu OpenGL
ile grafik kartına yüklemeyi gösterdim. DDS formatı sıkıştırılmış
dokuyu S3 firmasının geliştirmiş olduğu S3TC isimli doku sıkıştırma
algoritmasını kullanarak içinde bulundurur. Microsoft S3 firmasından
teknolojiyi lisanslamış ve DirectX framework üne DXTC (Direct X texture
compression technology) olarak gömmüştür. Dolayısı ile bu formattaki
dokuları kullanmak için s3tc eklentisini kullanmak gerekecek. Kullanım
mantığı ise kısaca şöyle: dds formatındaki dosya diskten ana belleğe
alınır. Bu dosyanın header ında bulunan bilgilerden dosyanın kullandığı
sıkıştırma formatının türü (DXT1,DXT3 yada DXT5) ve dosyanın boyutları
gibi bilgiler öğrenilir. Daha sonra glCompressedTexImage2DARB(...)
isimli eklenti fonksiyonu uygun S3 eklenti tanımlamaları
(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT gibi) ile beraber kullanılarak
sıkıştırılmış doku grafik kartına yüklenir. Bu kullanım şekli çalışma
zamanında doku sıkıştırmaya göre bazı avantajlara sahip. Bu avantajları
şöyle sıralayabiliriz:
- Çalışma zamanında doku sıkıştırma yönteminde diskte bulunan
sıkıştırılmış resim dosyasını bellekte açmak için fazladan kod ve işlem
zamanı gerekir (bu iş için genelde ekstra bir resim yükleme kütüphanesi
kullanılırdı..), DDS formatındaki resim dosyalarını yüklemek ise çok
daha kolaydır.
- Çalışma zamanında dokuyu sıkıştırmak için grafik kartı sürücüsü
sıkıştırma algoritmasını her doku için çalıştırmak zorundadır. Bu da
ufakta olsa bir işlem zamanına malolur..
- Çalışma zamanında sıkıştırılan dokuların görünümünün son halinden
emin olamassınız. Kullanılan generic sıkıştırma algoritması ekran kartı
sürücüsünden sürücüsüne ve ekran kartının üretici firmasına (NVidia
yada ATI gibi) göre değişebilir, kalitede farklılıklar oluşabilir. DDS
dosyalarının kullanımında ise S3TC sıkıştırması kullanıldığı için final
resimin görünümden tüm platformlarda emin olursunuz.
- Dokuları diskte DDS olarak tutan uygulamalar sıkıştırılmamış
resim formatlarında tutan uygulamalara göre (*.bmp gibi..) texture
yükleme zamanında oldukça fazla bir hız kazancı sağlarlar.
(dokularınızı zaten jpeg, yada png gibi formatlarda diskte tutuyorsanız
pekte bir fark göremessiniz.)
- Bir DDS dosyasının içine alt mipmap seviyelerine ait
görüntüleride istediğiniz gibi düzenleyip koyabilirsiniz. Yada DDS
üretici programınızın bu işi otomatik olarak yapmasını da
sağlayabilirsiniz.
Bu kadar avantajlı yönünü saydıktan sonra bir dezavantajınada
değinmeden geçmeyelim. DDS formatı DirectX tabanlı olduğundan OpenGL
ile kullanırken düşey doku koordinatlarını ters çevirmemiz gerekiyor,
veya resminizi Y ekseninde ter çevirerekde bu ufak problemin üstesinden
gelebilirsiniz.
Sonuç ve Örnek Kod:
Bu yazıda sıkıştırılmış doku kullanımının faydalarını anlattıp OpenGL
ile nasıl kullanılabileceğinden bahsettim. Dökümana eşlik eden VC++ 6.0
projesinde yazıda anlattığım kullanım yöntemlerinin uygulamalarını
bulacaksınız. Örneği hazırlarken başlangıç noktası olarak NVidia nın
sitesinden indirdiğim başka bir örnek projeyi referans olarak kullandım
(referans-3). Bu kod üzerinde gereksiz gördüğüm pek çok kısmı
çıkarttım, kendime göre değişiklikler yaptım ve daha anlaşılır hale
getirmek için açıklama satırları ekledim. Kod GLUT kullanıyor (eğer
sisteminizde yüklü değilse gerekli lib,dll ve header ları http://www.xmission.com/~nate/glut.html
adresinden yükleyebilirsiniz.), diskten tga dosyasını yükleyip daha
sonra bunu çalışma zamanında sıkıştırıyor, ayrıca yine diskten bir dds
dosyasını yükleyip direk olarak kullanıyor. Klavyeden 1,2 ve 3
tuşlarına basarak dokunun orijinal, sıkıştırılmış ve dds sıkıştırılmış
halleri arasında geçiş yapabilirsiniz. Elimden geldiğince açıklama
satırlarına yer verdim. Kodu anlamakta çok problem yaşamayacağınızı
düşünüyorum.
DDS dosyalarını pek çok popüler program ile oluşturabilirsiniz. NVidia
nın sitesinden Photoshop pluginleri indirilebiliyor. Bu pluginler Paint
Shop Pro ile birlikte de kullanılabiliyor. Ayrıca yine NVidia nın
sitesinde komut satırında çalışan bir dds converter da bulunuyor. ATI
de compressonator isimli kullanışlı bir dds converter hazırlamış. Bu
programlara erişmek için gerekli linkleri referanslar bölümünün sonunda
bulabilirsiniz.
Son olarak tavsiyem; eğer sıkıştırılmış doku kullanımı ile ciddi olarak
uğraşmak istiyorsanız mutlaka referans verdiğim kaynaklara bir göz
atın. DDS formatının DXT1, DXT3 ve DXT5 gibi farklı kullanım alanlarına
göre geliştirilmiş sıkıştırma algoritması seçenekleri bulunuyor. Doğru
formatı kullanmak önemli, mesela alpha kanalı içeren resimlerde DXT1 i
kullanmamak gerekiyor. Yine alpha kanalı kullanan resimlerde DXT5 DXT3
e göre daha iyi bir çıktı verirken, DXT3 daha fazla bir sıkıştırma
oranı yakalıyor.Yazı ile ilgili tüm öneriler, görüşler ve düzeltmeler
için sitemiz forumlarını kullanarak benimle temasa geçmekten
çekinmeyin. İyi eğlenceler.
[
VC++ 6.0 örnek proje dosyasını indirmek için tıklayın (90.9Kb)]
Referanslar:
1) Using Texture Compression in OpenGL (by Sebastien Domine):
http://developer.nvidia.com/object/texture_compression_OpenGL.html
2) OpenGL Extension Registry:
http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_compression.txt
http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_compression_s3tc.txt
3) Nvidia OpenGL Texture Compression/S3TC sample code:
http://developer.nvidia.com/object/OpenGL_S3TC_tutorial.html
4) Reality Engine Texturing Guidelines:
http://reality.artificialstudios.com/twiki/bin/view/Main/TextureGuidelines
5) DXTC Examples And Technical Comparison:
http://udn.epicgames.com/Two/TextureComparison
DDS gösterici / çevirici ve yardımcı araçlar:
NVidia Photoshop/Paint Shop Pro DDS pluginleri ve çeşitli faydalı DDS
araçları:
http://developer.nvidia.com/object/nv_texture_tools.html
ATI Compressonator:
http://www.ati.com/developer/compressonator.html
Mehmet Deniz Aydınoğlu :: 2005 :: www.oyunyapimi.org
|
|