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来给纹理单元绑定纹理,这样纹理就会被使用了

       

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




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

cocos2D-X源码分析之从cocos2D-X学习OpenGL(1)----cocos2D-X渲染结构

cocos2D-X 3.0渲染结构代码讲解,也是cocos2D-X源码讲解系列文章和从cocos2D-X学习OpenGL系列文章的开始...
  • bill_man
  • bill_man
  • 2014年06月29日 22:17
  • 12944

cocos2D-X源码分析之从cocos2D-X学习OpenGL(4)---混合

之前在项目中就使用过混合,但是研究的不深入,近期美术的一个需求让我下决心重新深入的研究了一下混合以及它在cocos2d-x中的使用,在这里分享给大家。...
  • bill_man
  • bill_man
  • 2015年12月30日 20:12
  • 4018

Cocos2d-x优化中纹理优化

1.纹理像素格式纹理优化工作的另一重要的指标是纹理像素格式,能够最大程度满足用户对保真度要求的情况下,选择合适的像素格式,可以大幅提高纹理的处理速度。而且纹理像素格式有与硬件有这密切的关系。下面我们先...
  • tonny_guan
  • tonny_guan
  • 2014年11月11日 20:01
  • 3404

cocos2D-X源码分析之从cocos2D-X学习OpenGL(14)----深度测试

深度测试类似于颜色缓冲(颜色缓冲存储片元颜色),深度缓冲是由窗口系统自动创建的,它储存着16、24或32位的浮点数的深度值。在大多数系统中,是24位的。     当深度测试开启时,openGL会用每个...
  • bill_man
  • bill_man
  • 2016年06月13日 10:29
  • 4448

Cocos2d-x 纹理管理

Cocos2d-x 纹理管理 声明:本文分析的是cocos2d-x-3.12的代码 当需要显示图片时则需要使用图片创建一个纹理,OpenGL内部可以把纹理对象渲染出来,把图片显示出来。当使用图片创建一...
  • wlk1229
  • wlk1229
  • 2017年03月01日 08:58
  • 496

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

1.Scheduler与Timer的关系相当DataManager与Data的关系。 2.Scheduler的两种定时模式,一种是customer selector模式,一种是update 模式。 ...
  • u011225840
  • u011225840
  • 2014年06月18日 17:14
  • 1586

基于Cocos2d-x学习OpenGL ES 2.0系列——编写自己的shader(2)

在上篇文章中,我给大家介绍了如何在Cocos2d-x里面绘制一个三角形,当时我们使用的是Cocos2d-x引擎自带的shader和一些辅助函数。在本文中,我将演示一下如何编写自己的shader,同时,...
  • czh3642210
  • czh3642210
  • 2017年07月17日 09:21
  • 304

《Cocos2d-x之Lua核心编程》读书笔记:Lua基础

Lua编程三类用户 需要一门简单的脚步语言嵌入到应用程序中的开发者 想要提高c/c++语言开发者 想要提高运行效率的脚步开发者 特点 易嵌入,可以方便的与c/c++编写的游戏逻辑互相调用 简单,不涉及...
  • c_boy_lu
  • c_boy_lu
  • 2016年01月29日 15:07
  • 1734

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

上一篇博客介绍了cocos2d-x中的着色器类相关的结构,以及着色器的一些原理,这一篇将介绍着色器语言。...
  • bill_man
  • bill_man
  • 2016年06月07日 11:54
  • 8227

cocos2D-X源码分析之从cocos2D-X学习OpenGL(3)----BATCH_COMMAND

个人原创,欢迎转载,转载请注明原文地址http://blog.csdn.net/bill_man上一篇介绍了QUAD_COMMAND渲染命令,顺带介绍了VAO和VBO,这一篇介绍批处理渲染命令Batc...
  • bill_man
  • bill_man
  • 2014年08月15日 20:52
  • 5364
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:cocos2D-X源码分析之从cocos2D-X学习OpenGL(8)----纹理
举报原因:
原因补充:

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