Blog Yazıları

SFML'de Vertex Kullanımı

SFML içerisinde OpenGL kütüphanesini kullanabilmekteyiz. std::vector yerine sf::VertexArray'de kullanabiliriz ancak bu yöntem bana daha kullanışlı geldi. Bununla ilgili olarak aşağıdaki kodu yazdım:
std::vector<sf::Vertex> vertices;

sf::Color colors[] = {
    sf::Color::Red,
    sf::Color::Green,
    sf::Color::Blue
};

float coords[] = {
    200.0f, 100.0f,
    100.0f, 300.0f,
    300.0f, 300.0f
};

for (int i=0; i<6; i++){
    vertices.push_back(sf::Vertex(sf::Vector2f(coords[i], coords[i+1]), colors[i/2], sf::Vector2f(100,100)));
    i++;
}
Sonrasında draw fonksiyonuna parametre olarak ekledik.
window.draw(&vertices[0], vertices.size(), sf::Triangles);
Ekran çıktısı ise aşağıdaki gibi:
Devamını Oku »

Oyun Geliştirme Günlüğü #1

SFML ile oyun geliştirmeye dünden itibaren başladım. SFML hakkında düne kadar herhangi bir bilgim veya tecrübem yoktu ancak güzel bir başlangıç yaptım gibi. İlk olarak SFML'in resmi sitesindeki dokümanları incelemeye başladım. Thread, mutex ve time handling gibi kavramları inceledim. Açıkçası vermiş oldukları kaynağı sevdim. Ayrıntıya kaçmadan iyi bir şekilde bilgilendirmişler. 

Oyun dosyalarımın yer aldığı proje dizinini belli bir hiyerarşide oluşturdum. Sonrasında Input, Window gibi dosya isimleri koydum. Temel olarak kendi küçük oyun motorumu yapmaya başladım. Ayrıca makefile dosyası yazdım. Ancak bu kısım beni en çok uğraştıran kısımdı. Makefile tam hakim olamadığım bir konu olduğu için dosyayı optimize etmeyi sonraya erteledim. O yüzden düz mantıkta bir makefile dosyası oluşturdum. Ancak proje içindeki dosyalar arttıkça mecbur olarak makefile dosyasını optimize etmem gerekecek.

Projeyi genel anlamda çalışır hale getirdim. Şu an pek bir şey ifade etmiyor olsa da en azından pencereyi çalışır hale getirdik. Örnek ekran görüntüsü aşağıdaki gibi:
demo_1
Oyun ne ile ilgili olacak hiçbir fikrim yok şu an. Aslında aklımda çok sey var ama bunları oyun içinde gerçekleştirebilir miyim, bilmiyorum. Şu an için basit mantık ile ilerleyeceğim.
Devamını Oku »

SFML'e Giriş

Bugün itibariyle SFML öğrenmeye başlıyorum. Bayağıdır ismini duyuyordum ancak kendisine pek sıcak bakmamıştım. Şu an ise bir heves geldi ve SFML kullanmak istiyorum 😐. Şu an kendisine resmi ana sayfa üzerinden çalışmaya başlayacağım. Buraya da yüksek ihtimalle bir ders serisi ekleyebilirim. En azından Türkçe kaynak olur.

SFML nedir ondan bahsedelim. SFML, yapılan uygulamaların geliştirilmesinde kolaylık sağlaması amacıyla modüller içerir. Bu modüller system, window, graphics, audio ve network modülleridir. SFML birçok platformda çalışmakla beraber ayrıca çeşitli programlama dilleri ile beraber kullanılabilir. Ben SFML için C++ programlama dilini ve g++ compiler kullanacağım. Bakalım sonu nereye varacak?

SFML hakkında ayrıntılı bilgi için: https://www.sfml-dev.org/
Devamını Oku »

Texture - Günlük Kayıt #3


  • Texture, nesneye ayrıntı vermek için kullanılan 2D görüntüdür. (1D ve 3D texturelar mevcuttur.)
  • Texture bize o nesnenin çok ayrıntılı olduğu hissiyatını vermektedir.
  • Texture kullanılacağı zaman her vertex hangi kısımdan özel parça alacağını belirleyen texture koordinatlara sahip olmalıdır.
  • Texture koordinatları 0 ile 1 aralığındadır.
  • Texture color'ı texture koordinatları kullanarak almak sampling olarak adlandırılır.
  • Texture koordinatları, texture image'in sol alt (0,0) köşesinden başlar, sağ üst köşesinde(1,1) biter. Bununla ilgili örnek bu bağlantıdan görülebilir. 
  • Texture koordinatları genelde (0,0) ve (1,1) arasında değişmektedir. Fakat bu koordinatların dışına çıkarsak OpenGL default olarak texture imageleri tekrar edecektir. (Kısacası verilen texture koordinatın floating olduğu için integer kısmını ihmal ediyoruz.) Ancak bu durum bize bağlı değişebilir:
    • GL_REPEAT: OpenGL'in default olarak texturelara yaptığı işlemdir. Dokular tekrar eder.
    • GL_MIRRORED_REPEAT: Yukarıdakinden farklı olarak her image'i her tekrarla birlikte yansıtır.
    • GL_CLAMP_TO_EDGE: Koordinatları 0 ile 1 arasında sabitler.
    • GL_CLAMP_TO_BORDER: Aralığın dışında kalan koordinatlara istenilen bir border renk verilir.
  • Bu parametreler glTexParameter* fonksiyonunda kullanılmaktadır. (3. parametre olarak)
  • Örnek: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
  • İlk argüman texture hedefini verir. 2D çalışıldığı için GL_TEXTURE_2D seçilir.
  • 2. argüman hangi seçeneği belirlemek istediğimizi ve hangi doku ekseni için söylememizi gerektirir. Bu yüzden WRAP seçeneğini yapılandırmak ve S ekseni için belirtmek istiyoruz. Aynı zamanda T ekseni içinde belirtebiliriz. Son seçenek ise yukarıda bahsettiğimiz texture wrapping mode ile alakalı.Eğer GL_CLAMP_TO_BORDER kullanılırsa yapılması gereken işlem glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_Color);
  • Texture filtreleme için oldukça önemli iki tane ayar var. Bunlar GL_NEAREST ve GL_LINEAR seçenekleridir.
    • GL_NEAREST: OpenGL'nin default doku filtreleme metodudur. Bu ayarda OpenGL merkez koordinatlarına en yakın olan pikseli seçer. Bir diğer ismi nearest neighbor filtering
    • GL_LINEAR: Texture koordinatın komşu texturelarından interpolated değer alır ve texturelar arasında ortalama bir renk elde eder.
    • Texture filtreleme, magnifying ve minifying olarak ayarlanabilir. glTexParameter* kullanılır.
    • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    • glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  • Mipmap denen önemli bir kavram söz konusudur. Seyrek bir ormanda olduğumuz düşünülsün. Bir tane yakında bir tane de uzakta ağaç olsun. Bu ağaçların sahip olduğu doku aynı ancak. Uzaktaki ağacın çözünürlüğü bizim için o kadar önemli değil. Bu yüzden farklı bir mipmap kullanmak iyi olacaktır. OpenGL nesneye olan mesafeye en iyi uyan farklı bir mipmap texture kullanacaktır. Nesne çok uzakta olduğu için, daha küçük çözünürlük kullanıcı tarafından fark edilmeyecektir. Performans açısından da önemlidir.
  • Bir texture'u elle mipmap'lamak yerine OpenGL bu işlemi glGenerateMipmap fonksiyonu ile bizim için gerçekleştiriyor.
Devamını Oku »

Shader ve Uniformlar | Günlük Kayıt #2


  • Shaderlar, en basit hali ile girdileri çıktılara dönüştüren programdır.
  • Shaderlar arası iletişim sadece input ve output ile mümkündür.
  • OpenGL donanımda 16 4-component vertex attribute sağlar. Ancak bazı donanımlarda bunu arttırmanın yolları olabilir. (GL_MAX_VERTEX_ATTRIBS araştırılabilir)
  • GLSL'de vektörler 1,2,3 veya 4 bileşenli(component) olabilir. Örnek: vec1, bvec2, vec2, vec3, bvec4, bvec3, uvec1, uvec4, vs. Ancak sadece vecn formunu kullanmak bizim için yeterli olabilir.
  • Vektörlerde swizzling denilen ilginç vektör seçimleri yapılabilir. Örnek: vec2 deneme = vector.xxxx; ya da vector2.xyxy gibi.
  • Vektör parametresi içinde vektör değişkeni kullanabiliriz. Bu durum esneklik sağlar.
  • Vertex shader'da layout (layout = x) kullanımını ihmal edebiliriz ama bu durumda glGetAttribLocation'ı kullanmamız gerekir.
  • Fragment shader'da bir output rengi belirlemeyi başaramazsak OpenGL nesnesini siyah beyaz yapar.
  • Shaderlar arası veri gönderim işlemi bir program nesnesini bağlarken yapılır.
  • uniformlar, uygulamamızda CPU'dan GPU'ya veri geçirmek için kullandığımız bir başka yoldur. vertex attribute'lere kıyasla uniformlar:
    • globaldir. Yani global olmasının anlamı tüm shader'larda bir tane olması anlamına gelmektedir. Tabi bir program objesi içinde. Başka bir shader uniforma rahatlıkla erişebilir.
    • uniform değerleri nasıl set edildiyse reset veya güncelleme yapılanan kadar o değerler tutulur.
  • shader içersinde tanımlanmış bir uniform hiç kullanılmazsa derlenmiş halinde bu uniform değişkeni kaldırılmış olur.
  • Uniform konumu bulurken glUseProgram kodundan önce kullanılabilir. Ancak uniform'u update ederken önceden glUseProgram'ı çağırmış olmalıyız. Bağlantıda yer alan kodu inceleyiniz.
Devamını Oku »

Günlük Kayıt #1

  • 3D koodinatları 2D piksellere dönüştürme işlemi, OpenGL'in graphics pipeline tarafından yönetilir.
  • Graphics pipeline
    • Vertex Shader
    • Shape Assembly
    • Geometry Shader
    • Rasterization
    • Fragment Shader
    • Tests and Blending
  • Kendi shaderlarımızı yazabileceğimiz bölümler:
    • Vertex Shader
    • Geometry Shader
    • Fragment Shader
  • Örneğin üçgen çizdirmek istersek yapmamız gereken verileri tanımlamak:
    • VBO oluşturmak
    • Bu VBO'ya unique id vermek (glGenBuffers(size, &VBO))
    • Belli bir VBO buffer tipi ile bağlamak. (glBindBuffer(GL_ARRAY_BUFFER, VBO))
    • Sonrasında tanımlanan veriyi bu bağlanmış olan VBO'ya göre o buffer tipine veri yüklemeyi gerçekleştirmek. (glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW*3 form alabilir*))
  • Yazılan shader programlarda kullanılan dil GLSL'dir.
  • Attribute tanımlarken in keyword kullanılır. 
  • Attribute değişkenin konumu layout (location = x) in vec3 a_variableName; şeklinde belirtilir.
  • OpenGL'de render olmadan önce vertex data nasıl yorumlanması gerektiği programcı tarafından belirtilmelidir. Örneğin VBO'da yer alan verinin yapısı şu şekilde olsun:
    • Stride: 12
    • offset: 0
    • Vertex 1
      • x1 → 4 byte (32-bit float) [0-4]
      • y1 → 4 byte (32-bit float) [4-8]
      • z1 → 4 byte (32-bit float) [8-12] 
    • Vertex 2
      • x2 → 4 byte (32-bit float) [12-16]
      • y2 → 4 byte (32-bit float) [16-20]
      • z2 → 4 byte (32-bit float) [20-24]
    • Vertex 3
      • x3 → 4 byte (32-bit float) [24-28]
      • y3 → 4 byte (32-bit float) [28-32]
      • z3 → 4 byte (32-bit float) [32-36]
    • Bu bilgiler ışığında vertex data'nın nasıl yorumlanması gerektiğini glVertexAttribPointer fonksiyonu ile söyleriz:
    • glVertexAttribPointer(x, 3(size), GL_FLOAT(data_type), GL_FALSE(normalized), 3*sizeof(float)(stride),(void*)0(offset));
    • x olarak temsil edilen parametre attribute location değeridir. Bu sayede hangi veriyi yapılandırmak istediğimizi belirtiyoruz. Konumunu ne olarak belirtmişsek o konumu vermeliyiz.
    • glVertexAttribPointer verileri hangi buffer GL_ARRAY_BUFFER'a bağlıysa ondan veriyi alır.
  • Vertex Attribute'lar default olarak devre dışıdır. Bu sebeple kullanabilmek için aktif edilmelidirler. Bunun glEnableVertexAttribArray(x) kullanılır.
  • VAO kullanımı ise bundan sonra ihtiyaç haline gelmektedir. VAO için VBO'ların depolandığı bir nesne olarak bahsedebiliriz. Bu nesne içinde positions, colors, normal vectors, texture_coords gibi veriler barındıran VBO olarak depolanmaktadır. VAO yani Vertex Array Object aslında bir attribute liste yapısıdır.
  • Bir şeyi çizmeden önce şu adımları uygulayabiliriz:
    • VAO, VBO oluşturulur.
    • VAO bağlanır.
    • VBO bağlanır.
    • VBO'ya ilgili veri verilir.
    • Veri uygun şekilde yorumlanır.
    • Döngü içinde VAO bağlanır.
    • Çizim metodu kullanılır.
Devamını Oku »