COM337 Bilgisayar Grafiği OpenGL ile Grafik Programlama Dr. Erkan Bostancı
İçerik Işık Resim ve Metin Görüntüleme Texture-mapping
Işık (1/3) OpenGL de bir sahne 8 farklı ışık kaynağı kullanabilir. İlk ışık kaynağı için specular ve diffuse parametreleri öntanımlıdır. Işığın çalışması için glshademodel ve glenable(gl_lighting) çağrılarının yapılması gerekir. Işık kaynakları her yönde (omnidirectional) ışık saçar ama spot ışık olarak da kullanılabilir. Renk değerlerindeki 4. parametre alpha ya da opaklık değeridir. Bu sayede transparan veya ışığı geçiren materyaller oluşturulabilir. Örnek 9
Işık (2/3) RGBA modunda her pikselin bir opaklık değeri vardır. Opaklık değerinin 0 olması o pikseli transparan yapar. Opaklık anti-aliasing de kullanılır. Kenar (edge) içeren bir piksel in bir kısmı alpha değerinde tutulur.
Işık (3/3) Örnek 11
Pikseller, imgeler ve metin OpenGL de bir pencerede bir imge göstermek için şu anki çizim yapılacak konumu ilgili dörtgenin sol alt tarafına getirip pikselleri çizeriz. Metin çizmek için, yine ilgili konuma gidip, tek tek karakterleri çizeriz. OpenGL hem bitmap fontları, hem de stroked fontları destekler. Stroke fontlar çizgilerden oluşur ve bunlara dönüşümler (scale, vs.) uygulanabilir. Metin çizerken, ışıkları kapatmak önemlidir, aksi takdirde OpenGL metinlere de gölgelendirme vermeye çalışır. Bir nedenden dolayı 3B koordinat sisteminizi pencere koordinatlarıyla eşleştirmek isterseniz, örnekteki reshape callback i bunu yapar. Örnek 12
Görüntüleme pipeline ını ters çevirmek Bazı uygulamalarda ekrandaki bir noktaya tıkladığınızda o noktanın 3B uzayda karşılığını bulmak istersiniz. Bu aslında projeksiyondan dolayı eksik tanımlı (ill-defined) bir problemdir ve ters projeksiyon net değildir. Fakat penceredeki (x,y) değerleriyle birlikte bir z değeri de belirtirsek, modelview ve projection matrislerinin tersinin alınmasını sağlayabiliriz. Bu z değeri yakın ve uzak kırpma düzlemleri arasında olmalıdır. gluunproject (winx, winy, winz // window position + z-value modelmatrix, // 16-element modelview matrix projmatrix, // 16-element projection matrix objx, objy, objz) // pointers for object-space position
Texture-mapping (1/7) Bir nesneye yapılan doku ataması (texture-mapping) o nesneyi görsel anlamda zenginleştirir. OpenGL 1, 2, 3 boyutlu texture ları destekler. Texture-mapping yalnızca RGBA modunda çalışır. Bu modda her pikselin bir opaklık değeri vardı. Örnek 13
Texture-mapping (2/7) OpenGL de doku ataması yaparken 3 adım vardır: 1. Öncelikle texture olarak kullanılacak imgeyi belirlememiz gerekli. Örnekte, init fonksiyonun içindeki 2 for döngüsü bir satranç tahtası texture ını oluşturuyor. 2. Ardından, OpenGL texture ı nasıl uygulayacağını belirten parametreleri tanımlıyoruz. 3. Son olarak da, noktalar için texture koordinatlarını tanımlıyoruz. Bu poligonların oluşturulduğu display callback i içinde yapılır ve texture koordinatları poligon un köşe koordinatları ile ilişkilendirilir.
Texture-mapping (3/7) Texture ın kendisini oluşturmanın yanı sıra, bütün parametre ayarlamaları init in içinde yapılıyor. glgentextures ve glbindtexture bir imge için texture nesnesi oluşturur. Önemli olan çağrı glteximage2d (GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA,GL_UNSIGNED_BYTE, image); İmgeyi texture map a dönüştürür.
Texture-mapping (4/7) Fonksiyonun parametreleri: 1. GL_TEXTURE_2D: 2 boyutlu texture kullandığımızı belirtir. 2. 0: texture map in derecesin en üst derece yapar. Bu mip-mapping de kullanılır. 3. GL_RGBA: imge verisi hem RGB kanallarını hem de alpha kanalını içerir. 4. WIDTH ve HEIGHT: imgedeki column ve row sayısı. 2 nin bir üstü olmalıdır. 5. 0: Texture map in hiç kenarının olmadığını belirtir. 6. GL_RGBA: kullanılacak texel türünü belirtir. 7. GL_UNSIGNED_BYTE: piksellerin veri türünü belirtir. 8. image: asıl imge verisini içeren pointer.
Texture-mapping (5/7) display callback inde texture mapping açılıyor (enable) ve gltextenvf yüzeydeki herhangi renk bilgisinin yerine texture olacağını belirtiyor. display in içinde 2 tane dörtgen çiziliyor ve her köşe için tanımlanacak texel köşe noktasından önce tanımlanıyor. glbegin (GL_QUADS); gltexcoord2f (0.0, 0.0); glvertex3f (-2.0, -1.0, 0.0); gltexcoord2f (0.0, 1.0); glvertex3f (-2.0, 1.0, 0.0);... Texture mapping nasıl yapılacağını söyleyen parametreleri de anlatacak olursak, init in içindeki gltexparameteri fonksiyonu bu işi yapıyor.
Texture-mapping (6/7) OpenGL de texture map in indeksleri s ve t olarak adlandırılır. Aşağıdaki çağrılar bu indekslerin 0-1 aralığından çıktığında ne yapılması gerektiğini söyler: gltexparameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT); gltexparameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); Burada texture ı tekrarlatmasını söylüyoruz. Bir texel in boyutunun oluşan görüntüdeki bir piksel ile tam olarak eşleşmesi her zaman olmaz. Geometriye göre bazen bir texel birden çok pikseli kaplar (magnification), bazen de bir piksel birden çok texel i kaplar (minification).
Texture-mapping (7/7) OpenGL texture-mapping i her pikseli, texture uzayındaki bir noktaya atarken her köşe ile ilgili değerleri interpolate eder. Bu performans açısından hızlıdır ama görüntü açısından sorunlar yaratabilir. Bu nedenden dolayı OpenGL bize filtreleme imkanı sunar. Nearest-neighbour Two-by-two average Programın hızlı çalışmasını istediğimizden nearest-neighbour kullandık: gltexparameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gltexparameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Aliasing (1/2) Texture-mapping nasıl çalışır? Yüzey render edilirken, frame buffer a yazılacak olan yüzey pikselleri texture map in indekslerine çevrilir. Scaling ve perspektif etkilerin kullanıldığı yüzeyler, orijinal texture map in scale inden farklı görünür. Bu da aliasing oluşturur. Bu sorun hareketli yüzeylerde daha fazla göze çarpar.
Aliasing (2/2) Çözüm: Farklı scale lerde kullanılacak farklı texture lar kullanmak. Mip-mapping Daha düşük çözünürlüklü texture lar kullanmak. Herbiri bir üst seviyenin yarı boyutunda. 32x32, 16x16, 8x8, 4x4, 2x2, 1x1 piksel boyutlarında.