如何在结构数组中设置统一值?

Posted

技术标签:

【中文标题】如何在结构数组中设置统一值?【英文标题】:How to set uniform values in an array of structs? 【发布时间】:2019-01-27 20:24:55 【问题描述】:

我正在尝试设置数组中结构的各个字段的值。问题在于,在着色器中,结构的每个字段都分配了值 0。

着色器:

struct Light

    vec3 position;
    vec3 color;
    float ambient;
    float diffuse;
    float specular;
    float exponent;
;

uniform Light lights[8];

C++:

struct Light

    vec3 position;
    vec3 color;
    float ambient;
    float diffuse;
    float specular;
    float exponent;
;

...

std::vector<Light> activeLights;

Light l;
l.position = vec3(-50.0f, 50.0f, 50.0f);
l.color = vec3(1.0f, 1.0f, 1.0f);
l.ambient = 0.15f;
l.diffuse = 0.6f;
l.specular = 0.25f;
l.exponent = 8.0f;
activeLights.push_back(l);

...

for (int i = 0; i < activeLights.size(); i++)

    glUniform3f(glGetUniformLocation(program, "lights[i].position"), 
                    activeLights[i].position.x,
                    activeLights[i].position.y,
                    activeLights[i].position.z
    );
    glUniform3f(glGetUniformLocation(program, "lights[i].color"),
                    activeLights[i].color.r,
                    activeLights[i].color.g,
                    activeLights[i].color.b
    );
    glUniform1f(glGetUniformLocation(program, "lights[i].ambient"), activeLights[i].ambient);
    glUniform1f(glGetUniformLocation(program, "lights[i].diffuse"), activeLights[i].diffuse);
    glUniform1f(glGetUniformLocation(program, "lights[i].specular"), activeLights[i].specular);
    glUniform1f(glGetUniformLocation(program, "lights[i].exponent"), activeLights[i].exponent);

我在调试器中多次检查了 c++ 端的值,那里一切正常。

有什么想法吗?

【问题讨论】:

"lights[i].position": 那是一个字符串,其中包含的内容正是写在那里的内容。 i 不会被数字神奇地取代。如果要将 i 替换为相应的数字,则必须使用 std::stringstream 或 snprintf 或类似的东西。 【参考方案1】:
"lights[i].position"

与某些脚本语言不同,C++ 没有将代码应用于字符串文字的机制。因此,"lights[i].position" 始终就是那个字符串。 'i' 不被认为是特殊的;它是字符'i'。

您真正想做的是根据变量 i 生成一个字符串。这很容易做到:

std::ostringstream strm;
strm << "lights[" << i << "]";
std::string light = strm.str();

有更有效的方法可以做到这一点,但这是 C++ 中最简单的方法。无论如何,如果性能真的很重要,您就不会在运行时查询统一位置。

现在,您必须为每个统一成员访问生成一个字符串,然后使用该字符串访问该统一成员。因此,对于每次访问,您都必须这样做:

    std::string str = light + ".position";
    glUniform3f(glGetUniformLocation(program, str.c_str()), 
                    activeLights[i].position.x,
                    activeLights[i].position.y,
                    activeLights[i].position.z
    );

您可以重复使用str,而不是定义新的字符串。

【讨论】:

好的,非常感谢!我想到了最复杂的解决方案,但我没有看到那个简单的错误^^

以上是关于如何在结构数组中设置统一值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应原生 mobx 中设置数组值?

如何在angular2中的数组中设置补丁值(更新嵌套值)?

如何在 mex 结构中设置向量元素

如何访问数组类型值并在两个不同的列中设置火花?

如何在本机反应中从平面列表中设置 Json 数组

如何在数组中设置特定对象的状态