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
forGL\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);