OpenGL Nasıl Çalışır - OpenGL Pipeline

Kerem TAN
5 min readSep 9, 2023

--

Merhaba sevgili okurlar,
OpenGL Pipeline’ı açıklamadan önce OpenGL’in ne olduğunu açıklamak daha iyi olacaktır.

OpenGL, platformlar arası çalışabilen ve grafik kartı ile programcılar arasında iletişim kurmaya yardımcı olan bir kütüphanedir. Farklı işletim sistemleri ve ekran kartları üzerinde bağımsız olarak çalışabilen bu kütüphane sayesinde video oyunları, simülasyonlar ve görsel efektler gibi 2D ve 3D grafik işemlerinin gerektiği işlemler gerçekleştirilebilir.

OpenGL kütüphanesi, programcı ile ekran kartı arasındaki iletişim kurma işini tek başına yapmaz. Bu konuda ona yardımcı olan bazı yardımcı kütüphaneler vardır. Aşağıda OpenGL’in yardımcı kütüphanelerinden bazıları ve bunlar hakkında kısa bilgiler yer almaktadır.

GLFW, OpenGL’in platformlar arası çalışabilen bir yardımcı kütüphanesidir. GLFW kütüphanesi, OpenGL ile işletim sistemi arasında iletişim kurarak OpenGL’de pencereleri yönetmemize; giriş-çıkış işlemlerini kontrol etmemize vb. işlemlere yardımcı olur.

GLAD ve GLEW de OpenGL’in platformlar arası çalışabilen yardımcı kütüphaneleridir.

OpenGL kullanan programlar çalışırken arka planda OpenGL’in dinamik kütüphanesi ile bağlantı kurmaları gerekir. OpenGL, kendisini kullanan programların; dinamik kütüphanesine bağlanabilmesi için dinamik yükleme yöntemini kullanır. GLAD ve GLEW kütüphaneleri de burada bize yardımcı olur. OpenGL’in dinamik kütüphanesine bağlanmak için kullanılırlar. İki kütüphaneden sadece birini kullanmak yeterlidir.

GLAD’ın çalışma şekli, programcı OpenGL’in dinamik kütüphanesinde ihtiyaç duyduğu fonksiyon adreslerini doğrudan yakalamak yerine GLAD kütüphanesine ihtiyaç duyduğu fonksiyonu söyler ve GLAD kütüphanesi ihtiyaç duyulan fonksiyonun adresini programcıya verir.

GLEW’in çalışma şekli, OpenGL dinamik kütüphanesindeki fonksiyonları sarmalayarak programcılara kullanımı daha kolay bir arayüz sunar.

OpenGL Pipeline Adımları

  • OpenGL ile bir şekil çizildiğinde belirli adımların izlenmesi gerekir.
  • Bu belirli adımlar, OpenGL Pipeline olarak adlandırılır.
  • OpenGL kütüphanesinde OpenGL Pipeline olarak adlandırılan bu adımları içeren bir program nesnesi bulunur. Böylece bir program nesnesi sayesinde OpenGL Pipeline’ı yönetebilir ve bazı belirli adımları istediğimiz gibi programlayabiliriz.

OpenGL ile bir şekil çizebilmemiz için gereken program nesnesinin içerdiği OpenGL Pipeline adımları, aşağıda kısaca açıklanmıştır.

Adım 1 - Vertex Specification

Programcı, Vertex Specification’da herhangi bir değişiklik ya da müdahale yapamaz.

Örneğin monitör üzerinde bir üçgen çizmek istiyoruz.

Çizilecek üçgenin her bir köşe noktasına vertex denir ve her bir vertex çizim alanında x, y ve z koordinat verilerine sahiptir.

Vertex’ler kullanılarak çizilen basit şekillere primitives/primitive’ler denir.
Örneğin çizmek istediğimiz üçgen şekli bir primitive’dir.

Verteks verileri, Vertex Specification’da render edilecek primitive/primitives için bir bit serisi olarak ayarlanır.

Adım 2 - Vertex Processing

Bir önceki adımda vertex olarak adlandırılan noktalar bu adımda render için işlenmeye başlar.
Bu adım birkaç alt adımdan oluşur. Teknik olarak diğer bazı adımlar da birkaç alt adım içermektedir ancak onların alt adımları ayrıca açıklanmayacaktır. Bu adımdaki alt adımların açıklanmasının nedeni, programcıların buradaki alt adımlar ile vertex’lerin işlenmesini doğrudan değiştirebilmesi veya müdahale edebilmesidir.

Adım 2.1 - Vertex Shader

Programcı, Vertex Shader’da bazı değişiklikler veya müdahaleler yapabilir.

Vertex Shader’ın amacı oluşturulacak olan 2D/3D modelin konumunu ve özelliklerini, vertex’leri kullanarak geometrik olarak hesaplamaktır.
Bu adımda GLSL komutları kullanılarak bazı müdahaleler yapılır.
Bir önceki adımdan bu adıma gönderilen vertex verileri bit tipinde bir veri serisi olarak gelir. Bu adımda GLSL komutları yazılırken bit verisinin tipi etiketlenebilir. Örneğin “layout(location=0)” komutu bir önceki adımda alınan vertex verisinin bir konum verisi olduğunu belirtmek için kullanılır.

Ayrıca, bir önceki adımda gönderilen vektör bu adımda 3 elemanlı bir vektörden (x,y,z koordinatları) 4 elemanlı bir vektöre dönüştürülür. Bu dönüşümü yapmak için vertex verisinin sonuna 1 sayısı eklenir. Bu şekilde yeni vektör [x, y, z, 1]’e dönüştürülmüş olur.

Bu vektör dönüşümünün amacı sonraki adımlarda matris çarpımının doğru yapılabilmesi içindir.

Vertices verisinin sonuna 1 eklenmesinin nedeni ise 1 sayısının çarpma işleminde etkisiz bir eleman olmasıdır.

Buradaki amaç sonraki adımlar için matris çarpımlarının orijinal veriyi bozmadan yapılabilmesidir.

Adım 2.2 - Tessellation

Programcı, Tessellation’da bazı değişiklikler veya müdahaleler yapabilir.

Bir önceki adımdan gönderilen veriler bu adımda daha küçük primitive’lere dönüştürülebilir çünkü primitive’leri daha küçük parçalara ayırarak 3D yüzeylere dinamik olarak daha fazla detay ve karmaşıklık eklenebilir.

Oluşturmak istediğimiz model/şekil bu şekilde daha gerçekçi hale dönüştürülebilir.

Adım 2.3 - Geometry Shader

Programcı, Geometry Shader’da bazı değişiklikler veya müdahaleler yapabilir.

Geometry Shader mantıksal olarak Vertex Shader’a benzer.
Tıpkı Vertex Shader’da vertex’ler(köşeler) kullanılarak geometrik şekillerin oluşturulması gibi Geometry Shader’da da bir önceki adımdan gönderilen primitive’ler kullanılarak daha karmaşık ve yeni primitive’ler oluşturulur.

Örneğin, üçgen şekilleri kullanılarak bir altıgen oluşturulması.

Adım 3 - Vertex Post-Processing

Programcı, Vertex Post-Processing’de herhangi bir değişiklik veya müdahale yapamaz.

Vertex ve Geometry Shader’da hesaplanan değerler istenirse bu adımda kaydedilebilir.

Bazen oluşturulmak istenen şeklin bulunduğu çizim alanı, şeklin görüntüleneceği monitörden daha büyük olabilir. Bu adımda monitörde görüntülenemeyecek primitive’ler çizim ekranından kaldırılarak gereksiz hesaplamaların önüne geçilir.

Bu işleme clipping adı verilir.

Adım 4 - Primitive Assembly

Programcı, Primitive Assembly üzerinde herhangi bir değişiklik ya da müdahale yapamaz.

Vertex’ler bir seri olarak işlenir ve bu adımda bu serilerden yeni şekiller render edilir.
Örneğin 9 elemanlı bir vertex serisinden 3 adet üçgen çizilmesi gibi.

Ayrıca Face Culling işlemi de bu adımda yapılır.
Face Culling işlemi perspektifte görünmeyen veya görülemeyecek kadar uzakta olan primitive’ler, çizim alanından çıkarılmasıdır.

Adım 5 - Rasterization

Programcı, Rasterization’da herhangi bir değişiklik veya müdahale yapamaz.

Bir önceki adımda oluşturulan geometrik şekiller bu adımda fragment data adı verilen piksellere dönüştürülür.

Çizimi yapılmak istenen şeklin/modelin her bir pikselinin rengi, derinliği gibi bilgiler bir sonraki adım için fragment data içerisinde saklanır.

Step 6 - Fragment Shader

Programcı Fragment Shader’da bazı değişiklikler veya müdahaleler yapabilir.

Bir önceki adımda fragment data olarak adlandırılan pikseller bu adımda işlenir. Özellikle oluşturulan şeklin/modelin her bir pikselinin renklendirilmesi bu aşamada yapılır.

Bu adımda piksellerin renklendirilmesinin yanı sıra her bir pikselin gölgelendirilmesi ve ışıklandırılması gibi işlemler de yapılır.

Yukarıda bahsedilen işlemleri gerçekleştirmek için tıpkı Vertex Shader’da olduğu gibi bu aşamada da GLSL komutları kullanılır.

Adım 7 - Per-Sample Operations

Programcı, Per-Sample Operations’da herhangi bir değişiklik veya müdahale yapamaz.

Bu adımda öncelikle Depth Test(Derinlik Testi) yapılır. Depth Test, çizilmek istenen fragment verisinin çizilip çizilmeyeceğinin belirlenmesi aşamasıdır.
Örneğin; çizilmek istenen fragment verisinin önünde başka bir fragment verisi varsa çizilmek istenen fragment verisi derinlik testinden geçemeyecektir.

Ayrıca Color Blending(Renk Karıştırma) işlemi de bu adımda gerçekleştirilir. Önceki adımlarda anlatılan işlemler kullanılarak fragment verilerindeki renkler birbirleri ile karıştırılır ve üst üste binen fragment verileri ile bu aşamada etkileşime girerler.

Tüm bu adımların sonucunda sahnenin render işlemi tamamlanır ve nihai 2D/3D şekil oluşturulur.

Buraya kadar okuduğunuz için teşekkür ederim.

Kod örneklerini buradan takip edebilirsiniz:

OpenGL hakkında daha fazla bilgi edinmek için buradaki videoya gidebilirsiniz:

Bu makalenin İngilizce versiyonuna buradan ulaşabilirsiniz:

--

--