我为光参数定义了一个包含两个向量的结构。结构是以类似的方式在C++和GLSL中定义的(注意:QVector3D封装了3个floats,而不是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();最后一个参数中的6应该指示每个数组元素使用原始浮点数数组中的6个GLfloats,也就是“元组大小”。
根据Qt文档,不应该使用6的元组大小(只允许1、2、3、4)。另一方面,QGLShaderProgram允许传递具有最多4x4项的矩阵。GLSL还允许有超过4个浮动的制服(根据这个例子)的结构。
这就引出了一个问题:
如何将浮点数/向量的结构作为一个统一数组传递给Qt?,如果不能使用Qt,我将调用GL函数来完成这个任务,但是如果Qt可以方便地为我做到这一点,我很感兴趣。
我当然试过上面的代码了。它将导致结构中的所有向量都被设置为0。
当我删除结构中的第二个参数并使用3的元组大小时,代码仍然不能工作!但是,当只在着色器中使用vec3 (仍然是宿主程序中只有一个QVector3D的结构,元组大小= 3)时,它可以工作。
因此,问题似乎是,自定义类型在OpenGL主机程序API中的处理方式不同,但Qt似乎不支持它。我目前使用两个均匀阵列(一个用于pos,一个用于强度)作为解决方案。
发布于 2013-05-24 17:48:20
Qt和这件事无关。
不能像传递值数组一样传递结构数组。如果有一个类型不是基本类型的统一数组,那么每个数组索引和该结构的每个成员都有一个统一名称。因此,您必须分别传递每个成员。
你必须这样做:
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);以此类推。
或者,您可以使用一个适当均匀块并免除所有这些。
发布于 2015-06-09 14:49:03
我使用一个模板函数:
template<class T> void setUniformArrayValue(QOpenGLShaderProgram *program,
                                       const QString& arrayName,
                                       const QString& varName,
                                       int index,
                                       const T& value)
{
    const char* name = QString("%1[%2].%3")
            .arg(arrayName)
            .arg(index)
            .arg(varName)
            .toStdString().c_str();
    program->setUniformValue(name, value);
}在该方案中:
for (int i = 0; i < m_lights.size(); i++) {
    setUniformArrayValue<QColor>(program, "lights", "ambient", i, m_lights[i].ambient());
    ...
}https://stackoverflow.com/questions/16739993
复制相似问题