Как установить одинаковые значения в массиве структур? - PullRequest
0 голосов
/ 27 января 2019

Я пытаюсь установить значения отдельных полей структур в массиве.Проблема в том, что в шейдере каждому полю структуры присваивается значение 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 ++ в отладчике, там все в порядке.

Есть идеи?

1 Ответ

0 голосов
/ 27 января 2019
"lights[i].position"

В отличие от некоторых языков сценариев, C ++ не имеет механизма для применения кода к строковому литералу.Таким образом, "lights[i].position" всегда является именно этой строкой.«я» не признается чем-то особенным;это символ '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 вместо определения новых строк.

...