繁体   English   中英

从C ++代码获取已编译的glsl shader统一参数的大小

[英]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].positionspheres[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
    }
}

您还可以将typeGL_FLOATGL_FLOAT_VEC3进行比较,以确定它是哪种数据类型。

请记住,如果您添加一个int count并为每个匹配项增加它。 然后,即使最后count3 这并不意味着可用元素0, 1, 2 它很容易是元素0, 5, 8

补充笔记:

  • name是一个以空值终止的字符串
  • %n是到目前为止已读取的字符数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM