从C++代码中获取已编译的 glsl 着色器统一参数的大小
Get the size of compiled glsl shader uniform parameter from C++ code
我正在尝试在已经编译的 glsl 着色器程序中获取统一参数的大小。我发现一些功能仅适用于默认类型的制服。但是有没有办法为自定义类型的统一参数做到这一点?
例如:
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()
和正则表达式或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
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 从C++代码中获取已编译的 glsl 着色器统一参数的大小
- GLSL 错误:"out"限定符仅对 GLSL 1.10 中的函数参数有效