glGetUniformLocation使用循环获取数组中的元素

时间:2016-05-30 13:45:12

标签: c++ opengl

我有一个有多个灯光的着色器,我想得到每个灯的均匀位置'属性,而无需为每个灯光手动输入。但是,由于glGetUniformLocation使用字符串找到了统一,我不能这样做。

for (unsigned int i = 0; i < MAX_LIGHTS; ++i) {
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_ON + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].on");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_TYPE + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].type");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_POSITION + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].position_cameraspace");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_COLOR + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].color");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_POWER + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].power");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_KC + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].kC");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_KL + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].kL");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_KQ + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].kQ");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_SPOTDIRECTION + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].spotDirection");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_COSCUTOFF + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].cosCutoff");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_COSINNER + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].cosInner");
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_EXPONENT + n] = glGetUniformLocation(shaderProgramID[PHONG], "lights[n].exponent");
}

例如,因为&#34;灯[n] .on&#34;是一个const char *,glGetUniformLocation找不到它,因为n不是数字。我怎么能这样做,我可以像这样循环?提前谢谢。

2 个答案:

答案 0 :(得分:1)

您只需根据需要动态构造字符串。

//Helper function that takes a `string`.
GLint GetUniformLocation(GLuint program​, const std::string &name)
{
  return glGetUniformLocation(program​, name.c_str());
}

for (unsigned int i = 0; i < MAX_LIGHTS; ++i) {
    shaderParameters[PHONG * U_TOTAL + U_LIGHT0_ON + n] =
      GetUniformLocation(shaderProgramID[PHONG], "lights[" + std::tostring(i) + "].on");
    //And so forth.
}

注意:以上假设您使用的是最新版本的C ++。

但是,正如246Nt所建议的那样,使用std140布局的UBO可以更轻松地更改此数据以便。但是,如果你使用非块制服,你可以使用explicit uniform locations,如果你有GL 4.3或ARB_explicit_uniform_location。这样,您就不必查询位置了;你知道它们是什么,因为你在着色器中设置了这些位置。并且将为每个子成员顺序分配数组/结构的每个组件的位置。

答案 1 :(得分:0)

我建议使用UBO:https://www.opengl.org/wiki/Uniform_Buffer_Object

这样你基本上只是发送&#39;通过一个统一的块,所有的光线同时发生。