OpenGL Kullanımı

Bu derste OpenGL'den pek fazla bahsetmeden, window paketiyle OpenGL'i nasıl kullanabileceğimize bakacağız. Bildiğiniz gibi OpenGL'in en büyük özelliklerinden biri taşınabilirliğidir. Bununla birlikte OpenGL ilk önce taranmış içeriğin (resmetme bağlamı, rendering context) oluşturulmasını gerektirir. Taranmış içerik, pek çok şey olmasına rağmen, taşınabilir değildir, her işletim sistemi bunu oluşturmak için kendine has bir yol kullanır. Bu yüzdendendir ki, insanlar çoğunlukla OpenGL'in her sistem üzerinde çalışabilmesini sağlayacak taşınabilir pencereleme / olay sistemleri için taşınabilir kütüphaneler kullanır. Bunu yapan en popüler kütüphaneler SDL ve GLUT'tur, fakat bunlar C ile yazılmış olduğundan C++ ile kullanılmaya her zaman elverişli değildir, özellikle de nesneye yönelimli bir yaklaşım izlemek istiyorsanız.


İlk Yapılandırma
SFML'de OpenGL'i kullanmak için yapmanız gereken tek şey Window.hpp başlığını programa dahil etmektir. OpenGL ve GLU başlıkları otomatik olarak programa dahil olacaktır böylece. Bu sizi bir önişlemci kullanmaktan kurtarmaktadır, çünkü OpenGL başlıkları her işletim sisteminde farklı isimlere sahiptir. Şimdi daha önceden öğrendiğimiz şekilde bir pencere oluşturarak ilerleyelim:
sf::Window App(sf::VideoMode(800, 600, 32), "SFML OpenGL");
OpenGL içerik oluşumu hakkında daha fazla kontrol istiyorsanız, derinlik arabelleği, şablon arabelleği ve örtüşme önler gibi ekstra grafik seçenekleri içeren bir yapıya geçebilirsiniz. Bunun için ContextSettings yapısını kullanabilirsiniz:
sf::ContextSettings Settings;
Settings.DepthBits = 24; // 24 bit derinlik arabelleği
Settings.StencilBits = 8; // 8 bit şablon arabelleği
Settings.AntialiasingLevel = 2; // 2 seviyeli örtüşmeönler
sf::Window App(sf::VideoMode(800, 600, 32), "SFML OpenGL", sf::Style::Close, Settings);
ContextSettings yapısının her bir üyesi belirli bir öntanımlı değere sahiptir, yani sadece sizin için önemli olan ayarları belirtmeniz yeterlidir. Donanım yapılandırmasına göre, istenen ayarların tamamı kullanıma uygun olmayabilir. Bu durumda SFML, makine tarafından desteklenen en yakın ayarları seçecektir. Tam olarak hangi değerlerin seçildiğini görmek için pencere yapılandırmasına bakabilirsiniz:
sf::ContextSettings Settings = App.GetSettings();
Pencere oluştuğunda, geçerli bir tarama içeriğine sahibiz demektir. Bu OpenGL ile ilgili yapılandırmaları yapmak için iyi bir zaman demektir:
// Renk ve derinlik temizleme değerlerini ayarla
glClearDepth(1.f);
glClearColor(0.f, 0.f, 0.f, 0.f); 
// Z-buffer'ı okuma ve yazma için aktifleşti
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE); 
// Bir perspektif izdüşümü ayarla
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.f, 1.f, 500.f);


Ana Döngü: Küp Çizme
Ana döngü daha öncekilerde olduğu gibi olay işleme ile başlıyor:
while (App.IsOpened())
{
    sf::Event Event;
    while (App.GetEvent(Event))
    {
        // Kapatıldığında veya Escape tuşuna basıldığında uygulamayı durdurmak için çeşitli kodlar
    }
Bunun dışında Resized olayını da izlememiz gerekiyor. Çünkü pencere boyutu değiştiği zaman, OpenGL görüş alanını yeni boyutla eşlenebilmesi için yeniden ayarlamalıyız. Görüş alanı, sahnenin görüntülendiği pencere alanıdır. Eğer yeni pencere boyutuna sığacak şekilde ayarlamazsanız, sahneniz pencerede istediğiniz gibi görüntülenmeyecektir.
if (Event.Type == sf::Event::Resized)
glViewport(0, 0, Event.Size.Width, Event.Size.Height);
Şimdi yeni bir kareyi taramaya başlayabiliriz. Herhangi bir OpenGL komutu çağırmadan önce, üzerinde işlem yapılacak olan pencerenin aktif olduğundan emin olmalıyız. Şu an sadece tek bir penceremiz olduğu için önemsemeyebiliriz ama birden fazla SFML penceresi ile çalışırken bunu mutlaka hesaba katmalıyız. Bir pencereyi aktif yapmak için onun SetActive fonksiyonunu çağırmamız yeterlidir:
App.SetActive();
Bundan sonra yapacağımız ilk şey, önceki karenin içeriğini silmek için renk ve derinlik önbelleklerini temizlemektir:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Şimdi bir küp çizmeye hazırız. İlk önce küpün konumunu ve yönelimini tanımlayalım. Yönelim, olaya biraz hareket katmak için o anki zamana göre değişecek.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.f, 0.f, -200.f);
glRotatef(Clock.GetElapsedTime() * 50, 1.f, 0.f, 0.f);
glRotatef(Clock.GetElapsedTime() * 30, 0.f, 1.f, 0.f);
glRotatef(Clock.GetElapsedTime() * 90, 0.f, 0.f, 1.f);
Sonrasında küpümüzü çiziyoruz:
glBegin(GL_QUADS);
    glVertex3f(-50.f, -50.f, -50.f);
    glVertex3f(-50.f, 50.f, -50.f);
    glVertex3f( 50.f, 50.f, -50.f);
    glVertex3f( 50.f, -50.f, -50.f); 
    glVertex3f(-50.f, -50.f, 50.f);
    glVertex3f(-50.f, 50.f, 50.f);
    glVertex3f( 50.f, 50.f, 50.f);
    glVertex3f( 50.f, -50.f, 50.f); 
    glVertex3f(-50.f, -50.f, -50.f);
    glVertex3f(-50.f, 50.f, -50.f);
    glVertex3f(-50.f, 50.f, 50.f);
    glVertex3f(-50.f, -50.f, 50.f); 
    glVertex3f(50.f, -50.f, -50.f);
    glVertex3f(50.f, 50.f, -50.f);
    glVertex3f(50.f, 50.f, 50.f);
    glVertex3f(50.f, -50.f, 50.f); 
    glVertex3f(-50.f, -50.f, 50.f);
    glVertex3f(-50.f, -50.f, -50.f);
    glVertex3f( 50.f, -50.f, -50.f);
    glVertex3f( 50.f, -50.f, 50.f); 
    glVertex3f(-50.f, 50.f, 50.f);
    glVertex3f(-50.f, 50.f, -50.f);
    glVertex3f( 50.f, 50.f, -50.f);
    glVertex3f( 50.f, 50.f, 50.f);
glEnd();
Son olarak da taranan sahneyi ekranda göstererek ana döngümüzü tamamlıyoruz:
App.Display();
İşte oldu, tüm bunları başarıyla yaptıktan sonra siyah ekran üzerinde dönmekte olan beyaz bir küpü izliyor olmalısınız. Her zamanki gibi ana döngüden çıktıktan sonra herhangi bir temizleme işlemi gerekmemekte.

Görmüş olduğunuz gibi SFML'de OpenGL kullanmak son derece kolaydır ve fazladan bir iş yapmanızı gerektirmez. Sadece birkaç satır kodla portatif ve nesne yönelimli bir OpenGL pencereleme sistemi elde edebilirsiniz.



Bu eğitselle ilgili diğer örneklere sfml-gelistirme deposundan ulaşabilirsiniz.


Kaynak: Window - Using OpenGL