cocos2D-X源码分析之从cocos2D-X学习OpenGL(8)----纹理

原创 2016年06月08日 12:09:30

       纹理(Texture)就是图片,它用来给物体增加细节,cocos2d-x中使用Texture2D类处理2D纹理贴图,本篇就从cocos2d-x中的Texture2D类介绍openGL纹理。

       首先介绍纹理坐标的概念,2D纹理是一个图像数据的二维数组。用2D纹理渲染时,纹理坐标用作纹理图像中的索引。一般来说,在3D内容创作程序中将制作一个网格,每个顶点都有一个纹理坐标。2D纹理的纹理坐标是用一对2D坐标(s,t)指定,有时也称作(u,v)坐标。这些坐标代表用于查找一个纹理贴图的规范化坐标,纹理图像的左下角由纹理坐标(0,0)指定,右上角由纹理坐标(1,1)指定,纹理坐标指明纹理图像的哪个地方采样。之后再所有的其他的像素上进行像素插值。

        处理贴图的代码如下:

    //生成贴图,并绑定
    glGenTextures(1, &_name);
    GL::bindTexture2D(_name);

    //纹理滤过方式
    if (mipmapsNum == 1)
    {
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _antialiasEnabled ? GL_LINEAR : GL_NEAREST);
    }else
    {
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _antialiasEnabled ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST);
    }
    
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _antialiasEnabled ? GL_LINEAR : GL_NEAREST );
    //放置方式
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
       首先是生成贴图和绑定。纹理对象是一个容器对象,保存渲染所需的纹理数据,例如图像数据、过滤模式和包装模式。在openGL中,纹理对象是一个无符号整数表示,该整数对象是个句柄,在创建的时候,glGenTextures生成的纹理对象是一个空的容器,用于加载纹理数据和参数。纹理对象在应用程序不再需要它们的时候要删除,使用glDeleteTexures实现。       

    if(_name != 0)
    {
        GL::deleteTexture(_name);
        _name = 0;
    }
       然后是绑定纹理,一旦纹理绑定到一个特定纹理目标,纹理对象在删除之前就一直绑定在它的目标。
       接下来是设置滤过方式和放置方式,在介绍滤过方式和放置方式之前,首先介绍glTexParameteri函数,它是用于设置贴图属性的函数,第一个参数是纹理目标,第二个参数是设置参数,第三个参数是纹理参数设置值。

       纹理坐标不依赖解析度,它可以是任何浮点数值,这样openGL需要描述哪个纹理图素对应哪个纹理坐标,openGL也有一个叫做纹理过滤的选项。有多种不同的选项,这里介绍几种:

        GL_NEAREST:从最靠近纹理坐标的纹理中获得一个单点样本。会选择最接近纹理坐标中心点的那个像素。

        GL_LINEAR:从最靠近纹理坐标的纹理中获得一个双线性样本。他会从纹理坐标的临近纹理像素进行插值,返回一个多个纹理像素的近似值。一个纹理像素距离纹理坐标越近,最终采样颜色越接近。

        另外几个过滤选项需要介绍一个mipmap的概念,mipmap的思路是构建一个图像链。mipmap贴图链始于原来指定的图像没后续的每个图像在每个维度上是前一个图像的一半,一直持续到最后达到1*1的纹理,如果图片要发生缩小而且你会担心性能,那么使用mipmap是大部分硬件上的最佳选择

        GL_NEAREST_MIPMAP_NEAREST:接收最近的mipmap级别,并使用线性采样。

        GL_NEAREST_MIPMAP_LINEAR:在两个mipmap之间进行线性插值,通过近邻插值采样。

        GL_LINEAR_MIPMAP_NEAREST:接收最近的mipmap级别,并使用线性插值采样。

        GL_LINEAR_MIPMAP_LINEAR:在两个相邻的mipmap进行线性插值,并使用线性插值采样。


      左边的采用近邻过滤,右边的采用线性过滤,可以看出,线性过滤更平滑。GL_TEXTURE_MIN_FILTER是设置图片缩小的过滤方式,GL_TEXTURE_MAG_FILTER设置放大的过滤方式。

       在openGL 3.0中,立方体过滤是无缝的,也就是说过滤核心跨越立方图不止一个面,核心将会从其覆盖的每个面中获得样本。无缝过滤在各个面形成了边缘形成了更平滑的过滤。

       纹理放置模式用于指定纹理超出范围时所发生的行为,openGL es中提供了三种:

      GL_ REPEAT:重复纹理

      GL_MIRRORED_ REPEAT:镜像重复

      GL_CLAMP_TO_EDGE:边缘拉伸

      三种不同的效果如下:

             

       接下来就是生成纹理,使用glTexImage2D函数:

glTexImage2D(GL_TEXTURE_2D, i, info.internalFormat, (GLsizei)width, (GLsizei)height, 0, info.format, info.type, data);
       第一个参数是纹理目标,2D纹理采用GL_TEXTURE_2D

       第二个参数是mipmap的纹理级别,第一个是0,后续递增。

       第三个参数是纹理存储格式,一般有GL_RGB,GL_RGBA等等

       第四个和第五个是纹理宽高。

       第六个参数是为了与openGL兼容的参数,忽略为0即可。

       第七个参数是纹理数据格式,一般有GL_RGB,GL_RGBA等等

       第八个参数是数据格式,GL_INT,GL_FLOAT等

       第九个参数是实际数据,从图片文件到实际数据其实是个复杂的过程,有时我们会采用第三方库来完成,因为图片的格式非常多,处理起来非常麻烦,cocos2d-x在Image类中处理这个事情,总之,到这里,我们可以拿到图片数据,并且把它传入进来。

       接下来就是激活并使用纹理。       

glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_2D, textureId);
       这段代码在ccGLStateCache.cpp中,这里有一个纹理单元的概念。一个纹理的位置成为纹理单元,默认激活的纹理单元位置是0,纹理单元的主要目的是让我们在着色器中使用多个纹理,通过激活纹理单元,我们可以给纹理单元绑定相应的纹理,它就像是一个停车位一样,openGL至少提供16个纹理单元可以使用。

       通过glActiveTexture来设置当前纹理单元,然后使用glBindTexture来给纹理单元绑定纹理,这样纹理就会被使用了

       

       能力不足,水平有限,如有错误,欢迎指出。




版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

让System.out.println回家种田

<script type="text/javascript"

cocos2D-X源码分析之从cocos2D-X学习OpenGL(20)----模型,网格和材质

openGL在cocos2d-x中的应用点,调用的api基本已经介绍的差不多了,这一篇介绍一些3d游戏中的概念,它们也和底层有一些关系,也是游戏中常用的一些封装。       当我们要在屏幕上绘制简单...

cocos2d-x 源码分析 总目录

这篇博客用来整理与cocos2d-x相关的工作,只要有新的分析、扩展或者修改,都会更改此文章。 祝大家愉快~ 1.源码分析 1.CCScrollView源码分析          http:/...

cocos2D-X源码分析之从cocos2D-X学习OpenGL(13)----模板测试

像素着色器调用完成后。模板测试就开始了,它可以丢弃片元,模板缓冲在渲染时获得有意思的效果。     模板缓冲中一个模板值有8位大小,每个窗口都会创建一个默认的模板缓冲,它可以通过数据控制屏幕显示,从而...

cocos2d-x 源码分析 : control 源码分析 ( 控制类组件 controlButton)

control的设计整体感觉挺美的,在父类control定义了整个控制事件的基础以及管理,虽然其继承了Layer,但其本身和UI组件的实现并没有关联。在子类(controlButton,control...

cocos2D-X源码分析之从cocos2D-X学习OpenGL(7)----GLSL

上一篇博客介绍了cocos2d-x中的着色器类相关的结构,以及着色器的一些原理,这一篇将介绍着色器语言。

Cocos 3D功能初探学习笔记(1)---摄像机

本篇首先介绍摄像机,其实2D时cocos引擎就有摄像机这个概念,每个节点都拥有一个摄像机类,当时的摄像机类的使用实例就是实现节点对象的缩放旋转,因为节点本身就自带这些功能,所以摄像机使用的场合并不多,...

cocos2D-X源码分析之从cocos2D-X学习OpenGL(9)----变换和坐标系统

本篇会介绍openGL中的变换和坐标系统,由于篇幅的问题,本篇文章不会把重点的笔墨放在数学基础,如果对数学概念有疑问的读者可以翻一下大学的线性代数教材。       首先是向量的概念,向量是既有大小又...

Cocos2d-x 源码分析 : Scheduler(定时器) 源码分析

1.Scheduler与Timer的关系相当DataManager与Data的关系。 2.Scheduler的两种定时模式,一种是customer selector模式,一种是update 模式。 ...

cocos2D-X源码分析之从cocos2D-X学习OpenGL(6)---cocos内置着色器

上一篇我们介绍了cocos2d-x绘制基本图形的基本流程,我们还留下了一个着色器的部分没有讲,本篇内容将从openGL的渲染流程讲起,介绍cocos2d-x中的着色器,openGL的渲染流程如图所示:...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)