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

Nic*_*lin 4 c++ opengl shader glsl

我正在尝试在数组中设置结构的各个字段的值.问题是在着色器中,struct的每个字段都赋值为0.

着色器:

struct Light
{
    vec3 position;
    vec3 color;
    float ambient;
    float diffuse;
    float specular;
    float exponent;
};

uniform Light lights[8];
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

我在调试器中多次检查了c ++端的值,一切都没问题.

有任何想法吗?

Nic*_*las 6

"lights[i].position"
Run Code Online (Sandbox Code Playgroud)

与某些脚本语言不同,C++没有将代码应用于字符串文字的机制.因此,"lights[i].position"总是完全是那个字符串.'我'不被认为是特别的; 这是角色'我'.

你真正想要做的是根据变量 生成一个字符串i.哪个可以轻松完成:

std::ostringstream strm;
strm << "lights[" << i << "]";
std::string light = strm.str();
Run Code Online (Sandbox Code Playgroud)

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

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

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

您可以重用str,而不是定义新字符串.