如何在OpenGL中动态跟踪纹理单位?



我目前正在为我正在从事的项目创建一个纹理类,我正在尝试从一开始就很好地创建东西,以防止将来出现头痛。

目前,我将纹理信息加载到 GPU 的方式如下:

void Texture::load_to_GPU(GLuint program)
{
    if(program == Rendering_Handler->shading_programs[1].programID)
        exit(EXIT_FAILURE);
    glUseProgram(program);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureID);
    GLint loc = glGetUniformLocation(program, "text");
    if(loc == GL_INVALID_VALUE || loc==GL_INVALID_OPERATION)
    {
        cerr << "Error returned when trying to find texture uniform."
            << "nuniform: text"
            << "Error num: " << loc
            << endl;
        return;
    }
    glUniform1i(loc,0);
}

但是,我希望能够动态确定纹理单位。

例如,与其硬编码统一名称"text",我想将字符串作为参数传递,并执行类似于glGetUniformLocation()但纹理单元的操作。

换句话说,我想选择纹理要动态绑定到的纹理单元,而不是硬编码它。

为此,我需要找到一个当前未使用的纹理单元,理想情况下是从最小到最大的纹理单元。

我可以使用哪组 OpenGL 函数来实现此行为?

编辑:

我需要实现我想要的行为的一个重要工具,我认为从原始帖子中不清楚的是:

一旦纹理单元绑定到采样器制服,我希望能够将纹理单元绑定到制服上。

所以如果纹理单元5绑定到统一的"sampler2d texture_5">

我想要一个函数,它采用统一标签并返回绑定到该标签的纹理单元。

我假设你已经包装了所有的纹理绑定/取消绑定。

如果是这样,您可以使用以下方法使用 O(n( 内存在 O(1( 时间内分配和释放纹理单位。

(我在其他任何地方都没有见过这种方法,也不知道这个数据结构的名称。如果有人知道它叫什么,我将不胜感激。

constexpr int capacity = 64; // A total number of units.
int size = 0; // Amount of allocated units.
std::vector<int> pool, indices;
void init()
{
    pool.resize(capacity);
    std::iota(pool.begin(), pool.end(), 0);
    indices.resize(capacity);
    std::iota(indices.begin(), indices.end(), 0);
}
int alloc()
{
    if (size >= capacity)
        return -1; // No more texture units.
    return pool[size++];
}
void free(int unit)
{
    // assert(indices[unit] < size) - if this fails, then you have a double free
    size--;
    int last_unit = pool[size];
    std::swap(pool[indices[unit]], pool[size]);
    std::swap(indices[unit], indices[last_unit]);
}

最新更新