Bir sürü yaklaşım var, ama hiçbiri mükemmel değil.
glAttachShader
Gölgelendiricileri birleştirmek için kod kullanarak paylaşmak mümkündür , ancak bu, yapı bildirimleri veya #define
-d sabitleri gibi şeyleri paylaşmayı mümkün kılmaz . İşlevleri paylaşmak için çalışır.
Bazı insanlar glShaderSource
, kodunuzdan önce genel tanımları hazırlamanın bir yolu olarak iletilen dizeleri kullanmaktan hoşlanır , ancak bunun bazı dezavantajları vardır:
- Gölgelendiriciden nelerin dahil edileceğini kontrol etmek daha zordur (bunun için ayrı bir sisteme ihtiyacınız vardır.)
- Bu, gölgelendirici yazarının
#version
GLSL spesifikasyonundaki aşağıdaki ifadeden dolayı GLSL'yi belirleyemediği anlamına gelir :
#Version yönergesi, her şeyden önce bir gölgelendiricide meydana yorumlar ve bosluklarla hariç gerekir.
Bu nedenle glShaderSource
, #version
bildirimlerden önce metin hazırlamak için kullanılamaz . Bu, #version
hattın glShaderSource
argümanlarınıza dahil edilmesi gerektiği anlamına gelir; bu, GLSL derleyici arayüzünüzün bir şekilde hangi GLSL sürümünün kullanılması beklendiği konusunda bilgilendirilmesi gerektiği anlamına gelir. Ek olarak, bir belirtmek değil #version
, GLSL derleyicisini GLSL sürüm 1.10 kullanmak için varsayılan yapacaktır. Gölgelendirici yazarlarının #version
betiğin içindeki değerini standart bir şekilde belirtmesine izin vermek istiyorsanız #include
, #version
ifadeden sonra bir şekilde insert'leri eklemeniz gerekir . Bu, #version
diziyi bulmak için GLSL gölgelendiriciyi açıkça ayrıştırıp, varsa ondan sonra eklemelerinizi yaparak , ancak#include
Bu kapanımların yapılması gerektiğinde daha kolay kontrol etmek için yönerge tercih edilebilir. Öte yandan, GLSL #version
satırdan önceki yorumları görmezden geldiğinden, yorumlarınızın içine eklemek için dosyanızın üst kısmına meta veri ekleyebilirsiniz (yuck.).
Şimdi soru şudur: Standart bir çözüm var mı #include
, yoksa kendi önişlemci uzantınızı mı kullanmanız gerekiyor?
Orada GL_ARB_shading_language_include
uzatma, ancak bazı sakıncaları da vardır:
- Yalnızca NVIDIA tarafından desteklenir ( http://delphigl.de/glcapsviewer/listreports2.php?listreportsbyextension=GL_ARB_shading_language_include )
- Önceden içerme dizelerini belirterek çalışır. Bu nedenle, derlemeden önce, dizenin
"/buffers.glsl"
(kullanılan şekilde #include "/buffers.glsl"
) dosyanın içeriğine buffer.glsl
(daha önce yüklediğiniz ) karşılık geldiğini belirtmeniz gerekir .
- (2) noktasında fark etmiş olabileceğiniz gibi, yollarınızın
"/"
Linux tarzı mutlak yollar gibi başlaması gerekir . Bu gösterim genellikle C programcılarına yabancıdır ve göreceli yolları belirleyemeyeceğiniz anlamına gelir.
Yaygın bir tasarım kendi #include
mekanizmanızı uygulamaktır , ancak bu zor olabilir çünkü #if
koşullu derlemeyi (başlık korumaları gibi) uygun şekilde ele almak için diğer önişlemci talimatlarını da ayrıştırmanız (ve değerlendirmeniz) gerekir.
Kendinizinkini uygularsanız, #include
nasıl uygulamak istediğiniz konusunda da bazı özgürlükleriniz vardır:
- Dizeleri vaktinden önce geçirebilirsin (gibi
GL_ARB_shading_language_include
).
- Bir içerme geri çağrısı belirtebilirsiniz (bu, DirectX'in D3DCompiler kütüphanesi tarafından yapılır.)
- Tipik C uygulamalarında olduğu gibi her zaman doğrudan dosya sisteminden okuyan bir sistem uygulayabilirsiniz.
Bir sadeleştirme olarak, ön işleme katmanınıza dahil her bir başlık için otomatik olarak başlık korumaları ekleyebilirsiniz, böylece işlemci katmanınız şöyle görünür:
if (#include and not_included_yet) include_file();
(Bana yukarıdaki tekniği gösterdiği için Trent Reed'e teşekkür ederim.)
Sonuç olarak, otomatik, standart ve basit bir çözüm yoktur. Gelecekteki bir çözümde, bazı SPIR-V OpenGL arayüzlerini kullanabilirsiniz, bu durumda GLSL - SPIR-V derleyicisi GL API dışında olabilir. Derleyicinin OpenGL çalışma zamanı dışında olması, #include
dosya sistemiyle arabirim kurmak için daha uygun bir yer olduğu için uygulamaların yapılmasını büyük ölçüde basitleştirir . Mevcut yaygın yöntemin, yalnızca herhangi bir C programcısının aşina olması gereken şekilde çalışan özel bir önişlemci uygulamak olduğuna inanıyorum.