Güncelleme
2014 yılında yazmış olduğum yazı ve videoları tekrar gözden geçirdiğimde içerik olarak ve düzen olarak eksik kaldığını fark ettim. O yüzden blogta yer alan ürettiğim içerikleri daha kaliteli olabilmesi amacıyla yakın zamandagüncelleyeceğim.
Yazıları ve videoları kalıcı olarak silmedim, sadece durumlarını taslak olarak değiştirdim. O yüzden gerekli bir durum olursa paylaşıma açacağım.
Ayrıca 2014 yılında kullanmış olduğun API ve geliştirme ortamlarını da güncelledim. Buna göre ileride kullanacağım API ve geliştirme ortamları şu şekilde olacak;
- Windows ile Ubuntu ortamında OpenGL uygulamaları geliştirebilmek için gereken “GL Context Creation” ve “GL Extension Wrangler” modülleri, GLUT ve Win32 yerineSDL2 veGLEW kütüphaneleri kullanılarak sağlanacak.
- Windows ile Ubuntu ortamında matris ve vektör işlemleri için GLM kütüphanesi kullanılacak.
- Windows ile Ubuntu ortamında geliştirme aracı olarakCode::Blocks 16.xx kullanılacak.
Yukarıda belirttiğim kütüphaneler hakkında bilgi edinmek için şu linkler kullanılabilir;
- SDL2 “Simple DirectMedia Layer” : http://libsdl.org/
- GLEW “OpenGL Extension Wrangler Library ” : http://glew.sourceforge.net/
- GLM “OpenGL Mathematics : http://glm.g-truc.net/0.9.7/index.html
C++ enum değişkenler nasıl yazdırılır ?
Enum değişkenlerin altındaki sayısal değerler direkt olarak yazdırılabilir. Yani aşağıdaki örnekteki gibi enum değişkenin değerini kolayca yazdırmak mümkün.
cout << AY_ARALIK << endl; // ekrana 12 yazar
Ancak, enum değerlerin değerleri yerine isimleri yazdırılmak istenirse işler biraz değişiyor. Enum değişkenlerin isimlerini yazdırmanın direkt olarak yolu bulunmamaktadır. Lakin bilinen yöntemler ile kolayca yapmak mümkün. Aşağıda vereceğim örnek bu yöntemlerdensadece biridir. Bu yöntem “<<” operatorunu overload ederek enum değişkenlerin yazdırılmasını sağlar. “printf” gibi fonksiyonlar ile çalışmaz. Fakat bu yöntem hem scoped hem de non-scoped enum türü için geçerlidir.
#include <iostream>using namespace std;// tanımlanan non-scoped enumenum msgSource{ SOURCE_API = 0x8246, SOURCE_SYSTEM = 0x8247, SOURCE_SHADER_COMPILER = 0x8248, SOURCE_THIRD_PARTY = 0x8249, SOURCE_APPLICATION = 0x824A, SOURCE_OTHER = 0x824B,};// << operatorunu overload eden fonksiyonstd::ostream& operator<<(std::ostream& os, msgSource c){ switch(c) { case SOURCE_API : os << "API"; break; case SOURCE_SYSTEM: os << "SYSTEM"; break; case SOURCE_SHADER_COMPILER : os << "SHADER_COMPILER"; break; case SOURCE_THIRD_PARTY : os << "THIRD_PARTY"; break; case SOURCE_APPLICATION : os << "APPLICATION"; break; case SOURCE_OTHER : os << "OTHER"; break; default : os.setstate(std::ios_base::failbit); } return os;}int main(){ msgSource msg= SOURCE_API; cout << "mesaj kaynagi = " << msg << endl;}
Yukarıdaki program çalıştırılırsa şu çıktı elde edilir;
sh-4.3$ g++ -std=c++11 -o main *.cpp sh-4.3$ main mesaj kaynagi = API
Enum tanımları için daha fazlasıhttp://en.cppreference.com/w/cpp/language/enum
C++ enum değişken türleri
C++ dilinde, enum türdeki değişkenler 2 farklı yol ile oluşturulabilir;
- Scoped enum
- Non-Scoped enum
Scoped enum örneği;
enum class msgSeverity { SEVERITY_HIGH = 0x9146, SEVERITY_MEDIUM = 0x9147, SEVERITY_LOW = 0x9148, SEVERITY_NOTIFICATION = 0x826B };
Non-Scoped enum örneği;
enum msgSeverity { SEVERITY_HIGH = 0x9146, SEVERITY_MEDIUM = 0x9147, SEVERITY_LOW = 0x9148, SEVERITY_NOTIFICATION = 0x826B };
Aralarındaki küçük fark tanımlama yaparken kullanılan “class” kelimesidir. “enum class” olarak tanımlanan enum türlerinin diğerine göre farkı şudur; Eğer tanımlanan enum class içerisindeki bir değere erişilmek istenirse, msgSeverity::SEVERITY_HIGH olarak erişilmesi gerekir.
Non-Scoped enumlarda ise, direkt olarak SEVERITY_HIGH olarak kullanıp enum altında yatan değer çekilebilir.
Peki neden Scoped enum ihtiyacı vardır ?
Eğer ERROR olarak bir enum değeri oluşturacaksanız derleme aşamasında, derleyici ERROR adı altında başka bir enum ismiyle karşılaşmaması gerekir. İşte bu noktada scoped enumlar devreye girerek birden fazla ERROR enum ismi tanımlanabilmesine olanak sağlıyor. Sonuç olarak, ERROR değerine erişirken XXX::ERROR veya YYY::ERROR olarak erişebilmeniz çakışmaları önlüyor.
Derleyici tarafından enum isimlerinde çakışma olduğunda üretilen hata mesajı şu şekildedir;
error: redeclaration of ‘errror’
Bu hata mesajı alındıktan sonra ya scoped enum kullanılabilir ya da enum ismi değiştirilebilir.
Enum tanımları için daha fazlasıhttp://en.cppreference.com/w/cpp/language/enum
Glew Experimental nedir ?
GLEW kütüphanesindeki glew.h dosyası içerisinde,glewExperimental adında bool değişken bulunmaktadır. Bu bool değişken, “initialization” işlemi yapılırken kullanılmaktadır. Amacı ise, ekran sürücüsünde yer alan OpenGL “extension” tespitinde “by-pass” yapmaktır.
Eğer OpenGL ile kullandığınız fonksiyon, ekran sürücüsü tarafından destekleniyor ancak GLEW tarafından algılanamıyorsa, manuel olarak glewExperimental değişkenine true değerini atayarak kullanılmak istenilen fonksiyon kullanılabilir.
Yalnız dikkat edilmesi gereken nokta şudur; eğer gerçekten istenilen fonksiyon ekran sürücüsü tarafından desteklenmiyorsa “run-time” aşamasında ciddi sorunlara yol açabilir.
Ayrıca “by-pass” işlemi “initialization” işleminden önce yapılmalıdır.
Kullanımı şu şekilde olabilir;
glewExperimental = GL_TRUE;GLenum err = glewInit();if( GLEW_OK != err ){cout << "glew initialization failed" << endl;}
Experimental Drivers
GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers, however, might not report every available extension through the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, theglewExperimental global switch can be turned on by setting it to GL_TRUE before calling glewInit(), which ensures that all extensions with valid entry points will be exposed.