Opengl glActiveTexture与glBindTexture的区别与联系

Opengl glActiveTexture与glBindTexture的区别与联系,opengl,textures,Opengl,Textures,根据我收集的信息,glActiveTexture设置活动的“纹理单元”。每个纹理单元可以有多个纹理目标(通常为GL_纹理_1D、2D、3D或立方体贴图) 如果我理解正确,您必须先调用glActiveTexture设置纹理单元(初始化为GL\u TEXTURE0),然后将(一个或多个)“纹理目标”绑定到该纹理单元 可用纹理单元的数量取决于系统。我在我的库中看到最多32个枚举。我想这基本上意味着我可以在任何时候在GPU内存中拥有我的GPU限制(我认为是16 8)和32个纹理中的较小者?我想有一个额外

根据我收集的信息,
glActiveTexture
设置活动的“纹理单元”。每个纹理单元可以有多个纹理目标(通常为GL_纹理_1D、2D、3D或立方体贴图)

如果我理解正确,您必须先调用
glActiveTexture
设置纹理单元(初始化为
GL\u TEXTURE0
),然后将(一个或多个)“纹理目标”绑定到该纹理单元

可用纹理单元的数量取决于系统。我在我的库中看到最多32个枚举。我想这基本上意味着我可以在任何时候在GPU内存中拥有我的GPU限制(我认为是16 8)和32个纹理中的较小者?我想有一个额外的限制,我不超过我的GPU的最大内存(假定为1GB)

我是否正确理解纹理目标和纹理单元之间的关系?假设我有16个单位,每个单位有4个目标,这是否意味着有空间容纳16*4=64个目标,还是不是这样

接下来,您通常需要加载纹理。您可以通过
glTexImage2D
执行此操作。其第一个参数是纹理目标。如果出现这种情况,那么我们基本上将“句柄”/“纹理名称”绑定到纹理目标,然后将纹理数据加载到该目标中,从而间接地将其与该句柄关联

GLTEX参数呢?我们必须绑定一个纹理目标,然后再次选择同一个目标作为第一个参数?或者,只要我们有正确的活动纹理单元,纹理目标就不需要绑定吗

glGenerateMipmap
也对目标进行操作…该目标仍必须绑定到纹理名称才能成功


那么,当我们想要绘制带有纹理的对象时,我们必须选择一个活动的纹理单元,然后选择一个纹理目标吗?或者我们选择一个纹理单元,然后我们可以从与该单元关联的4个目标中的任何一个获取数据?这一部分让我非常困惑。

想象一下GPU就像一个油漆加工厂

有许多水槽,可以将染料输送到一些喷漆机。在喷漆机中,染料被涂到物体上。这些坦克是纹理单位

这些水箱可以配备不同种类的染料。每种染料都需要一些其他种类的溶剂。“溶剂”是纹理目标。为了方便起见,每个罐都连接了一些溶剂供应,但每个罐一次只能使用一种溶剂。因此,有一个阀门/开关
纹理立方体贴图
纹理3D
纹理2D
纹理1D
。您可以同时将所有类型的染料注入槽中,但由于只有一种溶剂进入,因此只会“稀释”匹配的染料。因此,你可以将每种纹理进行粘合,但与“最重要”溶剂的粘合实际上会进入槽中,与它所属的染料混合


然后是染料本身,它来自一个仓库,通过“捆绑”它被注入到罐中。那是你的质地。

我试试看!这一切都没那么复杂,只是一个术语问题,希望我能说清楚


可以创建大致与系统中可用内存相同数量的纹理对象。这些对象包含纹理的实际数据(texel)以及glTexParameter提供的参数(请参见)

创建时,必须将一个纹理目标指定给一个纹理对象,该对象表示纹理的类型(
GL\u Texture\u 2D
GL\u Texture\u 3D
GL\u Texture\u CUBE
,…)

纹理对象和纹理目标这两项表示纹理数据。我们稍后再谈

纹理单位

现在,OpenGL提供了一组纹理单元,可以在绘图时同时使用。数组的大小取决于OpenGL系统的大小,您的有8个

可以将纹理对象绑定到纹理单元,以便在绘制时使用给定纹理

在一个简单易用的世界中,要使用给定的纹理绘制,需要将纹理对象绑定到纹理单元,然后执行(伪代码):

由于GL是一个状态机,唉,它不是这样工作的。假设我们的
textureObject
具有
GL\u TEXTURE\u 2D
纹理目标的数据,我们将前面的赋值表示为:

glActiveTexture(GL_TEXTURE0);                   // select slot 0 of the texture units array
glBindTexture(GL_TEXTURE_2D, textureObject);    // do the binding
请注意,
GL\u TEXTURE\u 2D
实际上取决于要绑定的纹理类型

纹理对象

在伪代码中,要设置纹理数据或纹理参数,请执行以下操作,例如:

setTexData(textureObject, ...)
setTexParameter(textureObject, TEXTURE_MIN_FILTER, LINEAR)
OpenGL不能直接操作纹理对象,要更新/设置它们的内容或更改它们的参数,必须首先将它们绑定到活动纹理单元(无论是哪个)。等效代码为:

glBindTexture(GL_TEXTURE_2D, textureObject)       // this 'installs' textureObject in texture unit
glTexImage2D(GL_TEXTURE_2D, ...)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
着色器

着色器可以访问所有纹理单元,它们不关心活动纹理

采样器制服是
int
值,表示要用于采样器的纹理单元的索引(而不是要使用的纹理对象)

因此,必须将纹理对象绑定到要使用的单位

采样器的类型将与纹理单元中使用的纹理目标进行匹配:
Sampler2D
for
GL\u texture\u 2D
,等等……

所有关于OpenGL对象的内容 OpenGL对象的标准模型如下所示

对象具有状态。将它们视为一个
结构
。因此,您可能有这样定义的对象:

struct Object
{
    int count;
    float opacity;
    char *name;
};
对象中存储了某些值,并且具有状态。OpenGL对象也有状态

变化状态 在C/C++中,如果您有一个类型为
Object
的实例,您将按如下方式更改其状态:
obj.count=5您将直接引用
struct Object
{
    int count;
    float opacity;
    char *name;
};
Object *g_objs[MAX_LOCATIONS] = {NULL};    
void BindObject(int loc, Object *obj)
{
  g_objs[loc] = obj;
}
void ObjectParameteri(int loc, ObjectParameters eParam, int value)
{
  if(g_objs[loc] == NULL)
    return;

  switch(eParam)
  {
    case OBJECT_COUNT:
      g_objs[loc]->count = value;
      break;
    case OBJECT_OPACITY:
      g_objs[loc]->opacity = (float)value;
      break;
    default:
      //INVALID_ENUM error
      break;
  }
}
Object *g_objs[MAX_OBJECTS][MAX_LOCATIONS] = {NULL};
int g_currObject = 0;

void BindObject(int loc, Object *obj)
{
  g_objs[g_currObject][loc] = obj;
}

void ActiveObject(int currObject)
{
  g_currObject = currObject;
}
glActiveTexture(GL_TEXTURE0 + i);