如何将多个立方体纹理传递到统一的采样器数组中?

时间:2018-02-18 02:42:37

标签: c++ opengl glsl shader

说我在着色器中有一个制服,声明为:

uniform samplerCube depth_maps[];

我在cpp一侧有一个纹理ID数组声明为:

vector<GLuint> depth_maps;

这是通过绘制到帧缓冲附加纹理创建的。

对于单个纹理,将信息传递到数组中的代码或多或少看起来像:

    glUseProgram(program);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    GLint loc = glGetUniformLocation(program, "depth_maps");
    if(loc == GL_INVALID_VALUE || loc==GL_INVALID_OPERATION)
    {
        cerr << "Error returned when trying to find depth_map uniform."
            << "\nuniform: text"
            << "Error num: " << loc
            << endl;
        return;
    }

    glUniform1i(loc,1);

此处GL_TEXTURE1表示此纹理将附加到纹理单元1(假设已经有纹理附加到GL_TEXTURE0)。

问题n1只有2个保证纹理单位,之后任何依赖于实现。

问题n2,即使我有很多它们我也只知道如何独立地和独立地传递它们(即为我想要传递的每个纹理重复上面的代码并为每个纹理定义一个新的制服)

如何将thsi数据作为连续的统一数组传递?

1 个答案:

答案 0 :(得分:2)

  

说我在着色器中有一个制服,声明为:

uniform samplerCube depth_maps[];

那将是一个编译错误。除了一个例外,GLSL 中的数组必须(最终)以编译时确定的大小声明。

但是,假设您已经为此数组提供了一个大小(并且您已确保使包含纹理图像单元的vector大小相同)。在统一数组上设置纹理图像单元的工作方式与在均匀数组上设置任何值的方式完全相同。

您可以单独执行此操作,并为每个数组元素使用不同的glUniform1i命令。

for(std::size_t i = 0; i < depth_maps.size(); ++i)
{
  std::ostringstream os;
  os << "depth_maps[" << i << "]";
  std::string name = std::move(os).str();
  GLint loc = glGetUniformLocation(program, name.c_str());
  glUniform1i(loc, depth_maps[i]);
}

或者您可以一次性设置它们。

GLint loc = glGetUniformLocation(program, "depth_maps");
glUniform1iv(loc, depth_maps.size(), depth_maps.data());