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

时间:2018-04-30 23:44:59

标签: c++ opengl

我目前正在为我正在开发的项目创建一个纹理类,我正在尝试从一开始就创建好东西以防止未来的麻烦。

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

func textView(_ textView: UITextView,
              shouldChangeTextIn range: NSRange,
              replacementText text: String) -> Bool {
    return false
}

但我希望能够动态确定纹理单元。

例如,我不想对统一名称&#34; text&#34;进行硬编码,而是希望将字符串作为参数传递,并对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); } 执行类似于纹理单元的操作。

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

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

我可以用什么样的OpenGL函数来实现这种行为?

编辑:

我需要一个重要的工具来实现我想要的行为,我相信在原帖中并不清楚:

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

因此,如果纹理单元5绑定到制服&#34; sampler2d texture_5&#34;

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

1 个答案:

答案 0 :(得分:1)

我假设你已经包裹了所有纹理绑定/解除绑定。

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

(我在其他任何地方都没有看到这种方法,也不知道这个数据结构的名称。如果有人知道它叫什么,我会很感激这些信息。)

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]);
}