c++ - 从 GLSL 着色器获取常量

标签 c++ opengl glsl constants shader

我有一个用 GLSL 编写的着色器,其中包含一组用于保存光照数据的结构。我使用常量来声明数组大小,这是一种很好的做法。假设这个变量声明为

const int NUM_POINT_LIGHTS = 100;

我如何使用 C++ 将这些数据从着色器中提取出来,以便我的 C++ 程序确切地知道有多少灯光可供它使用?我试过将其声明为

const uniform int NUM_POINT_LIGHTS = 100;

正如预期的那样,这不起作用(尽管很奇怪,看起来统一规范只是覆盖了 const 规范,因为 OpenGL 提示我正在用一个非常量值初始化一个数组)。我也试过了

const int NUM_POINT_LIGHTS = 100;
uniform numPointLights = NUM_POINT_LIGHTS;

这会起作用,除了 GLSL 优化掉未使用的制服这一事实,所以我必须跟踪 glsl 以认为制服以某种方式被使用以便能够获得数据。我一直无法找到任何其他方法来查询程序以获得常量值。有没有人知道我如何能够从着色器中提取常量,以便我的程序获取在着色器中按功能编码的信息以供使用?

最佳答案

我不认为你可以直接得到常量的值。但是,我认为您必须使用常量的值,很可能是统一数组的大小。如果是这种情况,您可以获得统一数组的大小,从而间接获得常量的值。

假设您的着色器包含如下内容:

const int NUM_POINT_LIGHTS = 100;
uniform vec3 LightPositions[NUM_POINT_LIGHTS];

那么可以先得到这个uniform的索引:

const GLchar* uniformName = "LightPositions";
GLuint uniformIdx = 0;
glGetUniformIndices(program, 1, &uniformName, &uniformIdx);

使用此索引,您可以检索此制服的属性:

const int nameLen = strlen("LightPositions") + 1;
const GLchar name[nameLen];
GLint uniformSize = 0;
GLenum uniformType = GL_NONE;
glGetActiveUniform(program, uniformIdx, nameLen, NULL,
                   &uniformSize, &uniformType, name);

uniformSize 应该是 NUM_POINT_LIGHTS 常量的值。请注意,我还没有尝试过这个,但我希望我根据文档得到了正确的论点。

一个有点难看但可能非常实用的解决方案当然是从着色器源代码中解析值。由于在将它传递给 glShaderSource() 之前无论如何都需要读取它,因此挑选常量值应该很容易。

还有另一种选择,如果您的主要目标是避免在多个地方使用常量,则在您的 C++ 代码中定义它,并在读入着色器代码之后、传递之前动态地将常量定义添加到着色器代码中它进入 glShaderSource()

关于c++ - 从 GLSL 着色器获取常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26541144/

相关文章:

c++ - 为什么没有 std::future::try_wait()?

c++ - 未解析的符号:sql::mysql::get_driver_instance(void)

java - LWJGL - 调用了当前上下文中不可用的函数

c++ - 在 OpenGL 中创建 GUI,可能吗?

opengl - 有了 OpenCL,GLSL 的意义何在?

c++ - Boost Asio 没有正确阅读

c++ - bool 自动转换为 nullptr_t

C++ OpenGL 绘制像素

c++ - 如何使用级联阴影贴图制作柔和阴影?

opengl - GLSL:关于连贯的限定词