学习是一件开心的额事情
玩过游戏的同学们,都知道在游戏人物身上穿的那个叫皮肤,专业点将那个就叫做纹理图像。GLSL 支持在顶点和片段着色器使用纹理图像。
下面的这个表解释了每种采样器的作用,不需要记忆,使用时,进行查阅即可!
采样器名称 | 描述 |
---|---|
sampler1D | 访问1D 纹理图像 |
isampler1D | 访问1D 纹理图像 |
usampler1D | 访问1D 纹理图像 |
sampler2D | 访问2D 纹理图像 |
isampler2D | 访问2D 纹理图像 |
usampler2D | 访问2D 纹理图像 |
sampler3D | 访问3D 纹理图像 |
isampler3D | 访问3D 纹理图像 |
usampler3D | 访问3D 纹理图像 |
samplerCube | 访问立体纹理图像 |
isamplerCube | 访问立体纹理图像 |
sampler1DArray | 访问1D 纹理图像数组 |
isampler1DArray | 访问1D 纹理图像像数组 |
usampler1DArray | 访问1D 纹理图像像数组 |
sampler2DArray | 访问2D 纹理图像数组 |
isampler2DArray | 访问2D 纹理图像像数组 |
usampler2DArray | 访问2D 纹理图像像数组 |
sampler2DRect | 访问2D 纹理矩形 |
isampler2DRect | 访问2D 纹理矩形 |
usampler2DRect | 访问2D 纹理矩形 |
sampler1DShadow | 访问1D 阴影纹理 |
isampler1DShadow | 访问1D 阴影纹理 |
usampler1DShadow | 访问1D 阴影纹理 |
samplerCubeShadow | 访问立体纹理 |
samler1DArrayShadow | 访问1D阴影纹理的一个数组 |
samler2DArrayShadow | 访问2D阴影纹理的一个数组 |
samler2DRectShadow | 访问2D阴影纹理矩阵 |
samplerBuffer | 访问纹理缓冲区 |
isamplerBuffer | 访问纹理缓冲区 |
usamplerBuffer | 访问纹理缓冲区 |
第一步.采样器必须在着色器中声明为uniform,切记他们的赋值必须来自应用程序中,采样器也可以作为函数的参数,但必须是类型匹配的采样器 第二步.采样器在着色器中使用之前必须分配一个纹理单元,并且只能通过glUniformli()、glUniformliv() 进行初始化(把采样器应该使用的纹理单元的索引作为参数)
Glint texsampler;
texSampler = glGetUniformLocation(program,"tex ");
glUniformli(texSampler,2);
第三步 .在着色器内部对一副问题图片进行采样时,需要使用已经声明且与一个纹理单元相关联的采样器变量。举个例子: 我们对一个与Sampler 2D 变量tex 相关联的二维纹理图像进行采样,并把采样结果和片段颜色进行组合,提供与在纹理环境下使用GL_MODULATE 模式相同的结果:
uniform sampler2D tex;
void main(){
gl_fragColor = gl_color *texture2D(tex,gl_texCoord[0].st)
}
uniform sampler1D coords;
uniform sampler3D volume;
void main()
{
vec3 texCoords = texture1D(coords,gl_TexCoord[0].s);
vec3 volumeColor = texture3D(volume,texCoords);
}
有个问题先说一下:尽管GLSL 使得数组可用,不管是在着色器中使用静态初始值,还是作为值得集合呈现为uniform变量中的一个数组,在这两个情况下,都有可能出现超出可用大小限制的数组.我们可能把这样一个值得表存储在一个纹理图像中,然后,在纹理中操作纹理坐标来访问想要访问的值。对于这个问题,更加直接的解决方案是纹理缓冲区,为什么这样说呢?纹理缓冲区是缓冲对象的一种特定的类型,类似于一维纹理,可以在说色器中使用一个整数值来索引,但是,它提供了较为昂贵的纹理内存的资源,因此支持较大的数据集合。 创建纹理缓冲区的步骤: 1.初始化数据 glBufferData() 2.把该缓冲区绑定到一个纹理缓冲区中 glTexBuffer()
void glTexBuffer(GLenum target,GLenum internalFormat,GLuint buffer)
把缓冲区对象buffer 和target 关联起来,这导致buffer 中的数据格式被解释为拥有internalFormat 的格式. target:必须为GL_TEXTURE_BUFFER interalFormat 纹理格式: GL_R8,GL_R16,GL_R16F,GL_R32F,GL_R81,GL_R16I,GL_R32I,GL_R81UI,GL_R16UI,GL_R32UI,GL_RG8,GL_RG16,GL_RG16F,GL_RG32F,GL_RG81,GL_RG16I,GL_RG32I,GL_RG8UI,GL_RG16UI,GL_RG32UI,GL_RGBA8,GL_RGBA16,GL_RGBA16F,GL_RGBA32F,GL_RGBA8I,GL_RGBA16I,GL_RGBA32I,GL_RGBA8UI,GL_RGBA16UI,GL_RGBA32UI 通过调用glActiveTexture() 来指定那个纹理单元和纹理缓冲区相关联。
纹理的使用在OpenGL 中是比较重要的一块内容,必须要掌握!