OpenGL 纹理单元的使用步骤:
glActiveTexture 函数详解
glBindTexture 函数详解
glUniform1i 函数详解
片元着色器
precision mediump float;
uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;
void main()
{
(u_TextureUnit, v_TextureCoordinates);
}
示例1:
//—————————使用纹理———————————
// Set the active texture unit to texture unit 0.
glActiveTexture(GL_TEXTURE0);
// Bind the texture to this unit.
glBindTexture(GL_TEXTURE_2D, textureId);
// Tell the texture uniform sampler to use this texture in the shader by telling it to read from texture unit 0.
glUniform1i(uTextureUnitLocation, 0);//将片元着色器中的uTextureUnitLocation纹理采样器(sample2D)和纹理单元0对应起来。
glActiveTexture(GL_TEXTURE0)表示把活动的纹理单元设置为纹理单元0,调用glBindTexture将textureId指向的纹理绑定到纹理单元0,最后,调用glUniform1i把选定的纹理单元传递给片元着色器中的u_TextureUnit(sampler2D)。
参考:
//—————————使用纹理———————————
示例2:
//获取shader里面uniform变量的地址
int tex1_location=glGetUniformLocation(m_uProgram, "tex1");
int tex2_location=glGetUniformLocation(m_uProgram, "tex2");
int tex3_location=glGetUniformLocation(m_uProgram, "tex3");
//对这几个纹理采样器变量进行设置
glUniform1i( (GLint)tex1_location, 0);//对应0号纹理单元
glUniform1i( (GLint)tex2_location, 1);//对应1号纹理单元
glUniform1i( (GLint)tex3_location, 2);//对应2号纹理单元
//后面渲染的时候,设置三成纹理
(GL_TEXTURE0 + 0);
(GL_TEXTURE_2D, texture1Id);
(GL_TEXTURE0 + 1);
(GL_TEXTURE_2D, texture2Id);
(GL_TEXTURE0 + 2);
(GL_TEXTURE_2D, texture3Id);
所以glActiveTexture第几层,并不表示是shader里面第几个采样器,
//中间有glUniform1i进行纹理层和采样器地址进行绑定
glBindTexture
void glBindTexture(GLenum target, GLuint texture );
函数参数的含义:
target —— 纹理被绑定的目标,它只能取值GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D或者GL_TEXTURE_CUBE_MAP;
texture —— 纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用。
纹理名称与相应的纹理内容位于当前GL rendering上下文的共享对象空间中。
glBindTexture的使用方法实际上体现在两个地方:
首先是载入纹理时,将载入的纹理与纹理分配号绑定在一起。也就是给当前的纹理分配相应的纹理号。
其次载入多个纹理之后,需要在多个纹理之间进行绑定,先使用glActiveTexture函数激活某个纹理单元然后需要使用glBindTexture函数进行纹理绑定。
二维纹理创建流程:创建纹理的过程主要是在GPU的内存中载入纹理图片
1.先使用glGenTextures函数生成一个纹理ID
2.使用glBindTexture(GL_TEXTURE_2D,.)函数绑定此纹理ID到OpenGL的GL_TEXTURE_2D渲染上下文中
3.使用glTexParameterf函数设置此纹理的过滤参数
4.使用glTexImage2D函数将CPU内存图像数据传输到GPU内存中同时也设置当前纹理的纹理id为刚刚生成的纹理id。此步完成了纹理图片在GPU内存中的载入。
5.glBindTexture(GL_TEXTURE_2D, 0); //将2D纹理绑定到默认的纹理,一般用于打破之前的纹理绑定关系,使OpenGL的纹理绑定状态恢复到默认状态,到此一个2维纹理创建完毕。
二维纹理使用流程:
1.先使用glGetUniformLocation函数获取fragmentShader内的uniform纹理变量
2.使用glUniform1i将获取的uniform纹理变量和某个纹理单元(纹理单元从0号纹理单元开始)对应起来
3.使用glActiveTexture函数激活某个纹理单元(例如激活0号纹理单元 0号纹理单元默认已经激活) glActiveTexture激活函数之后最好跟上glBindTexture绑定函数
4.使用glBindTexture函数将纹理绑定到使用glActiveTexture函数激活的那个纹理单元。
注意此步glBindTexture函数的意义和创建纹理时使用的此函数的意义不同,创建纹理时glBindTexture函数的意思是将GPU内的纹理数据和纹理id对应起来,既创建纹理时为载入纹理到此纹理id处,
而此处的glBindTexture函数的意义是绑定当前纹理id到激活的纹理单元。既此处为指定使用哪个纹理。
在绑定纹理前必须要确保此纹理单元已经激活,0号纹理单元默认激活。
此时OpenGL 的rendering渲染上下文中的纹理就是使用glBindTexture函数绑定的纹理单元了。
纹理单元能否同时工作?
纹理单元是可以同时工作的,多个纹理的shader中多个纹理是同时工作的,并发工作的。
glActiveTexture(GL_TEXTURE0); //在绑定纹理之前先激活纹理单元
glBindTexture(GL_TEXTURE_2D, texture);
例如:
// 在程序开始时:分配好纹理编号,并载入纹理
( /* ... */ );
载入第一幅纹理
(GL_TEXTURE_2D, texture_ID_1);
( /* ... */ );
...
载入第二幅纹理
(GL_TEXTURE_2D, texture_ID_2);
( /* ... */ );
...
注意此时两个纹理单元在同时工作
// 在绘制时,绑定并使用纹理,不需要再进行载入 但需要绑定纹理
...
绑定第一幅纹理
(GL_TEXTURE_2D, texture_ID_1); // 指定第一幅纹理
绑定第二幅纹理
(GL_TEXTURE_2D, texture_ID_2); // 指定第二幅纹理
参考文章:
http://www.jianshu.com/p/2d31eae7c3d8