Bir sürü yaklaşım var, ama hiçbiri mükemmel değil.
glAttachShaderGö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
#versionGLSL 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, #versionbildirimlerden önce metin hazırlamak için kullanılamaz . Bu, #versionhattın glShaderSourceargü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 #versionbetiğin içindeki değerini standart bir şekilde belirtmesine izin vermek istiyorsanız #include, #versionifadeden sonra bir şekilde insert'leri eklemeniz gerekir . Bu, #versiondiziyi bulmak için GLSL gölgelendiriciyi açıkça ayrıştırıp, varsa ondan sonra eklemelerinizi yaparak , ancak#includeBu kapanımların yapılması gerektiğinde daha kolay kontrol etmek için yönerge tercih edilebilir. Öte yandan, GLSL #versionsatı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_includeuzatma, 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 #includemekanizmanızı uygulamaktır , ancak bu zor olabilir çünkü #ifkoş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, #includenası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ı, #includedosya 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.