[英]Get the size of compiled glsl shader uniform parameter from C++ code
我試圖在已經編譯的glsl shader程序中獲得統一參數的大小。 我發現一些功能僅適用於默認類型的制服。 但是,有沒有一種方法可以對具有自定義類型的統一參數進行處理呢?
例如:
struct Sphere
{
vec3 position;
float raduis;
};
#define SPHERES 10
uniform Sphere spheres[SPHERES];
我假設您的最終目標基本上是spheres.length
,結果是10
。
最佳的方法是將該長度存儲在其他位置,因為無論如何在着色器編譯后就無法更改大小。
沒有簡單的方法來獲取數組的長度。 因為本身沒有任何數組。 編譯時,數組的每個元素(以及結構的每個元素)最終成為它們自己的統一體。 通過執行以下操作可以明顯看出這一點:
glGetUniformLocation(program, "spheres[4].position")
問題是,如果您的着色器僅使用spheres[4].position
和spheres[8].position
則所有其他spheres[x].position
可能會被優化掉,因此將不存在。
那么如何獲得統一的數組長度?
您可以通過使用glGetActiveUniform()
和regex或sscanf()
來完成此操作。 假設您要檢查有多少個spheres[x].position
,那么您可以執行以下操作:
GLint count;
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count);
const GLsizei NAME_MAX_LENGTH = 64
GLint location, size;
GLenum type;
GLchar name[NAME_MAX_LENGTH];
GLsizei nameLength;
int index, charsRead;
for (GLint i = 0; i < count; ++i)
{
glGetActiveUniform(program, (GLuint)i, NAME_MAX_LENGTH, &nameLength, &size, &type, name);
if (sscanf(name, "spheres[%d].position%n", &index, &charsRead) && (charsRead == nameLength))
{
// Now we know spheres[index].position is available
}
}
您還可以將type
與GL_FLOAT
或GL_FLOAT_VEC3
進行比較,以確定它是哪種數據類型。
請記住,如果您添加一個int count
並為每個匹配項增加它。 然后,即使最后count
為3
。 這並不意味着可用元素0, 1, 2
。 它很容易是元素0, 5, 8
。
補充筆記:
name
是一個以空值終止的字符串 %n
是到目前為止已讀取的字符數
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.