使用 QGLShaderProgram 将自定义类型(结构)uniform 从 Qt 传递到 GLSL

2023-12-31

我定义了一个包含两个向量的光参数结构。该结构体在 C++ 和 GLSL 中都以类似的方式定义(注意:QVector3D封装 3floats, not doubles):

C++主机程序:

struct LightParameters {
    QVector3D pos;
    QVector3D intensity;
};

片段着色器:

struct LightParameters {
    vec3 pos;
    vec3 intensity;
};

在片段着色器中,我还定义了以下制服。灯的数量限制为 8 个,因此统一数组具有恒定的大小(但仅numLights实际使用):

const int maxLights = 8;
uniform int numLights;
uniform LightParameters lights[maxLights];

在主机程序中,我定义灯光并将它们传递给着色器(QGLShaderProgram):

static const int maxLights = 8;
LightParameters lights[maxLights];

int numLights = 1;
lights[0].pos = {0, 1, 0};
lights[0].intensity = {1, 1, 1};

shaderProgram->bind();
shaderProgram->setUniformValue("numLights", numLights);
shaderProgram->setUniformValueArray("lights", reinterpret_cast<GLfloat*>(lights), maxLights, 6);
shaderProgram->release();

The 6最后一个参数中应该表明每个数组元素使用6GLfloat来自原始浮点数组的 s,又名“元组大小".

根据 Qt 文档,不应使用大小为 6 的元组(仅允许使用 1、2、3、4)。另一方面,QGLShaderProgram 允许传入最多包含 4x4 条目的矩阵。 GLSL 还允许包含超过 4 个浮点数的制服结构(根据这个例子 https://www.opengl.org/wiki/Uniform_%28GLSL%29).

这就引出了一个问题:

如何使用 Qt 将浮点/向量结构作为统一数组传递?如果无法使用 Qt,我将调用 GL 函数来执行此操作,但我很感兴趣 Qt 是否可以方便地为我执行此操作。

当然我还是尝试了上面的代码。它会导致结构中的所有向量都设置为 0。

当我删除结构中的第二个参数并使用元组大小 3 时,代码仍然无法工作!然而,当刚刚使用vec3在着色器中(仍然是主机程序中具有一个 QVector3D 的结构,元组大小 = 3),它可以工作。

所以问题似乎是自定义类型在OpenGL主机程序API中的处理方式不同,但Qt似乎不支持它。我目前使用两个统一数组(一个用于位置,一个用于强度)作为解决方法。


Qt 与此无关。

You cannot传递数组structs就好像它是一个数组values。如果您有一个类型不是的统一数组基本类型 http://www.opengl.org/wiki/GLSL_Type#Basic_types,那么每个数组索引和该结构的每个成员都有一个separate统一位置与separate统一名称 http://www.opengl.org/wiki/Uniform_%28GLSL%29#Uniform_management。因此,您必须通过每个成员分别地.

你必须这样做:

shaderProgram->setUniformValue("lights[0].pos", lights[0].pos);
shaderProgram->setUniformValue("lights[0].intensity", lights[0].intensity);
shaderProgram->setUniformValue("lights[1].pos", lights[1].pos);
shaderProgram->setUniformValue("lights[1].intensity", lights[1].intensity);
shaderProgram->setUniformValue("lights[2].pos", lights[2].pos);
shaderProgram->setUniformValue("lights[2].intensity", lights[2].intensity);

等等。

或者你可以只使用适当的均匀块 http://www.opengl.org/wiki/Uniform_Buffer_Object并免除所有这些。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 QGLShaderProgram 将自定义类型(结构)uniform 从 Qt 传递到 GLSL 的相关文章

随机推荐