美文网首页音视频
OpenGLES 之纹理

OpenGLES 之纹理

作者: Terrnce | 来源:发表于2017-05-10 17:18 被阅读75次

    纹理

            纹理是一个用来保存图像的颜色元素值的OpenGL ES 缓存。它可以控制一个渲染的三角形中每个像素的颜色。纹理可以使用任何图像,包括树木、云彩、机器、人物。当把纹理应用到几何图形中后,会使渲染的场景更显自然,会使三角形的复杂组合像是真实的物体而不是只有颜色的面。在纹理的缓存中保存的颜色值可能要耗费很多的内存,所以,应该尽量使用最小的图像来产生可以接受的渲染结果。

    纹素

              当用一个图片初始化一个纹理缓存后,在这个图像中的每个像素变成了纹理中的一个纹素。与像素类似。纹素保存颜色数据。要说区别。就是像素有具体的尺寸大小,而纹素没有,纹素存在于一个没有尺寸的数学坐标系中。

    纹理坐标系

    图1-1(纹理坐标系)

             纹理坐标系中有一个命为 S 和 T 的2D轴(上面画错了,x当成是S,y当成是T)。在一个纹理中无论有多少纹素,纹理的尺寸永远在S轴上是从 0 - 1.0 ,在T 轴上 是从 0 - 1.0.比如:一张图片宽是100像素,高是100像素。那S轴的1.0就表示截取图片的宽是100像素,如果S轴是0.5,则只会截取到图片的宽是50像素,图片只会显示一半。

    片元

             每个顶点坐标的X、Y、Z坐标被转换成视口坐标后,GPU会设置转换生成的三角形内的每个像素的颜色。转换几何形状数据为帧缓存中的颜色像素的渲染步骤叫做点阵化(rasterizing),每个颜色像素叫做片元(franment)

    映射

              程序需要指定怎么对齐纹理和顶点,以便让GPU知道每个片元的颜色由哪些纹素来决定。这个对齐又叫做映射(mapping)。

             其实每个顶点除了给定的X、Y、Z坐标,每个顶点还给出了U和V的坐标值。U坐标会映射纹理中的S轴,V坐标会映射到T轴。

    取样

             GPU会根据每个片元的U、V位置从绑定的纹理中选择纹素。这个过程叫做取样。取样会把纹理的S和T坐标系中与每个渲染的三角形的顶点的U、V坐标匹配起来。例如:一个U、V坐标为{0.5,0.5}的片元会被当前绑定的纹理中最接近中间位置的纹素着色。

    取样模式

    glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

    GL_TEXTURE_MIN_FILTER   多个纹素对应一个片元时

    GL_TEXTURE_MAG_FILTER 没有足够多的纹素来唯一性地映射一个片元,会有放大纹理的效果

    GL_LINEAR  当使用指定参数 GL_TEXTURE_MIN_FILTER,会使用线性插法来混合这些颜色以得到片元最终的颜色,

    GL_LINEAR当使用指定参数GL_TEXTURE_MAG_FILTER,会混合附近纹素的颜色来计算片元的颜色,会有一个放大纹理的效果,并会让它模糊地出现在渲染的三角形上

    GL_NEAREST  与片元U、V坐标最接近的纹素的颜色会被取样,当指定参数是 GL_TEXTURE_MAG_FILTER,会有一个放大纹理的效果

    除了上面这放大和缩小的过滤选项之外,当U、V坐标的值小于0或者大于1的时候,有以下两种选择,要么尽可能多的重复纹理以填满映射到几何图形的整个U、V区域,要么每当片元的U、V坐标超出纹理的S、T坐标系范围的时候,取样纹理边缘的纹素。

    glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);

    glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);

    glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);

    glTexParameteri (GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

    GL_TEXTURE_WRAP_S 和 GL_TEXTURE_WRAP_分别代表纹理坐标系的S 和T轴

    GL_REPEAT :代表重复纹理

    GL_CLAMP_TO_EDGE:代表取边缘纹理

    代码实现

    1.定义一个结构体

    三角形顶点数据结构体

    2.设置上下文,创建绑定顶点缓存区域,分配内存

    创建绑定顶点缓存区域,分配内存

    3.创建绑定顶点索引缓存区域,分配内存

    创建绑定顶点索引缓存区域,分配内存

    4.设置属性

    5.添加纹理

    6.绘制

    7.最后进行销毁

    8.运行结果

    在这个demo第二个例子中我们还用到了一个新的函数,这里说一下。

    glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);

    // 用来更新一个已有缓冲区对象中的一部分数据

    @param target 用来指定需要更新的缓冲区对象的类型,如 GL_ARRAY_BUFFER

    @param GLintptr 要从什么地方开始更新原来的数据(以字节为单位)

    @param size 需要更新的数据量的大小

    @param data 个指向新数据源的指针,将新的数据源拷贝到缓冲区对象中完成更新

    GitHub:

    https://github.com/weixin1/OpenGLES-Learn

    相关文章

      网友评论

        本文标题:OpenGLES 之纹理

        本文链接:https://www.haomeiwen.com/subject/bntytxtx.html