//data: 图片文件数据  dataLen: 文件长度
bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
{
bool ret = false; do
{
CC_BREAK_IF(! data || dataLen <= 0); unsigned char* unpackedData = nullptr;
ssize_t unpackedLen = 0; //解压缩pvr.ccz格式的图片
//detecgt and unzip the compress file
if (ZipUtils::isCCZBuffer(data, dataLen))
{
unpackedLen = ZipUtils::inflateCCZBuffer(data, dataLen, &unpackedData);
}
//解压缩pvr.gz格式的图片
else if (ZipUtils::isGZipBuffer(data, dataLen))
{
unpackedLen = ZipUtils::inflateMemory(const_cast<unsigned char*>(data), dataLen, &unpackedData);
}
else
{
unpackedData = const_cast<unsigned char*>(data);
unpackedLen = dataLen;
}
//识别文件类型
_fileType = detectFormat(unpackedData, unpackedLen); switch (_fileType)
{
case Format::PNG:
ret = initWithPngData(unpackedData, unpackedLen);
break;
...
//后面就是依据文件类型来进行图片解码初始化
} while (0); return ret;
}

这里先介绍下图片解码到载入再到显示的流程。以后再具体地介绍每种格式图片的解码。

Texture2D * TextureCache::addImage(const std::string &path)
{
...
//新建一个Image对象
image = new (std::nothrow) Image();
CC_BREAK_IF(nullptr == image); //图片解码
bool bRet = image->initWithImageFile(fullpath);
CC_BREAK_IF(!bRet); //新建一个2D的纹理
texture = new (std::nothrow) Texture2D(); //開始初始化纹理
if( texture && texture->initWithImage(image) )
{
...
}
} //使用指定像素格式来初始化(默认是auto,依据图片解码的结果来确定)
bool Texture2D::initWithImage(Image *image, PixelFormat format)
{
...
//获取当前的OpenGL环境
Configuration *conf = Configuration::getInstance();
//推断纹理大小是否超出限制
int maxTextureSize = conf->getMaxTextureSize();
... //获取mipmap贴图的数量
if (image->getNumberOfMipmaps() > 1)
{
CCLOG("cocos2d: WARNING: This image has more than 1 mipmaps and we will not convert the data format");
//载入mipmap贴图
initWithMipmaps(image->getMipmaps(), image->getNumberOfMipmaps(), image->getRenderFormat(), imageWidth, imageHeight); return true;
}
else if (image->isCompressed())
{
...
initWithData(...)
...
return true;
}
else
{
...
initWithData(...)
...
return true;
}
} bool Texture2D::initWithMipmaps(MipmapInfo* mipmaps, int mipmapsNum, PixelFormat pixelFormat, int pixelsWide, int pixelsHigh)
{
...
//设置像素的行字节对齐,在一定平台下有性能的提高。并且若不加注意,会导致glTexImage中系函数的读取越界
//Set the row align only when mipmapsNum == 1 and the data is uncompressed
if (mipmapsNum == 1 && !info.compressed)
{
unsigned int bytesPerRow = pixelsWide * info.bpp / 8; if(bytesPerRow % 8 == 0)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
}
else if(bytesPerRow % 4 == 0)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
else if(bytesPerRow % 2 == 0)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
}
else
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
}else
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
...
//生成纹理索引
glGenTextures(1, &_name);
//bindTexture2函数中会调用glActiveTexture,glBindTexture来制定纹理单位和绑定纹理
GL::bindTexture2D(_name); //依据mipmap贴图数和是否设置抗锯齿来选择纹理滤波方式,关于纹理滤波的选择后面会具体的再分析下
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 ); for (int i = 0; i < mipmapsNum; ++i)
{
unsigned char *data = mipmaps[i].address;
GLsizei datalen = mipmaps[i].len; //纹理映射一个指定的纹理图像的一部分到每一个开启了纹理映射的图元上。在当前段着色器或顶点着色器使用内建纹理搜索函数时。贴图被启用。 if (info.compressed)
{
//压缩格式生成纹理
glCompressedTexImage2D(GL_TEXTURE_2D, i, info.internalFormat, (GLsizei)width, (GLsizei)height, 0, datalen, data);
}
else
{
//生成2D纹理
glTexImage2D(GL_TEXTURE_2D, i, info.internalFormat, (GLsizei)width, (GLsizei)height, 0, info.format, info.type, data);
} if (i > 0 && (width != height || ccNextPOT(width) != width ))
{
CCLOG("cocos2d: Texture2D. WARNING. Mipmap level %u is not squared. Texture won't render correctly. width=%d != height=%d", i, width, height);
} GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
CCLOG("cocos2d: Texture2D: Error uploading compressed texture level: %u . glError: 0x%04X", i, err);
return false;
}
//四分之中的一个大小的mipmap
width = MAX(width >> 1, 1);
height = MAX(height >> 1, 1);
} _contentSize = Size((float)pixelsWide, (float)pixelsHigh);
_pixelsWide = pixelsWide;
_pixelsHigh = pixelsHigh;
_pixelFormat = pixelFormat;
_maxS = 1;
_maxT = 1;
//关闭alpha渐变
_hasPremultipliedAlpha = false;
_hasMipmaps = mipmapsNum > 1; // shader
setGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE));
}

对于非mipmaps的贴图直接指定为已mipmapsNum为1的形式进行初始化就可以,纹理纹理渲染完毕就可以增加到显示队列,当然这里仅仅是先简介下,关于渲染流程等我写完图片的解码部分再回来补充~

未完待续…

cocos2dx的图片载入的更多相关文章

  1. Cocos2d-x 3.0心得(01)-图片载入与混合模式

    近期開始用cocos2dx 3.0做东西,略有心(cao)得(dian),略微作下记录吧. v3.0相对v2.2来说,最引人注意的,应该是对触摸层级的优化.和lambda回调函数的引入(嗯嗯.不枉我改 ...

  2. cocos2d-x 获取图片的某像素点的RGBA颜色 -转

    cocos2d-x 获取图片的某像素点的RGBA颜色  原文:http://www.cnblogs.com/jaoye/archive/2013/02/19/2916501.html 没做过 太多的图 ...

  3. Android图片载入框架最全解析(一),Glide的基本使用方法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53759439 本文同步发表于我的微信公众号.扫一扫文章底部的二维码或在微信搜索 郭 ...

  4. Android批量图片载入经典系列——afinal框架实现图片的异步缓存载入

    一.问题描写叙述 在之前的系列文章中,我们使用了Volley和Xutil框架实现图片的缓存载入,接下来我们再介绍一下afinal 框架的使用. Afinal 是一个android的http框架.sql ...

  5. 一个方便的图片载入框架——ImageViewEx

    我的博客:http://mrfufufu.github.io/ 一.前言 近期在整理项目中的一些代码,以备即将开展的新项目中使用,刚刚整理到一个图片载入的 lib.用起来很的简单,和 picasso ...

  6. Android Handler 异步消息处理机制的妙用 创建强大的图片载入类

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号: ...

  7. Android图片载入缓存框架Glide

    Glide开源框架是Google推荐的图片载入和缓框架,其在Github上的开源地址是:https://github.com/bumptech/glide 当然一个Google推荐的框架肯定就是Vol ...

  8. 安卓图片载入之使用universalimageloader载入圆形圆角图片

    前言 话说这universalimageloader载入图片对搞过2年安卓程序都是用烂了再熟悉只是了.就是安卓新手也是百度就会有一大堆东西出来,今天为什么这里还要讲使用universalimagelo ...

  9. Universal-Image-Loader(UIL)图片载入框架使用简介

    这个也是近期项目中使用到的第三方图片载入框架.在这里也自己总结一下,简单的介绍一些使用的方式. UIL图片载入框架特点 简单介绍: 项目地址:https://github.com/nostra13/A ...

随机推荐

  1. Linux基本命令(9)定位、查找文件的命令

    定位.查找文件的命令 命令 功能 命令 功能 which 从path中找出文件的位置 find 找出所有符合要求的文件 whereis 找出特定程序的路径 locate 从索引中找出文件位置 9.1 ...

  2. spring初探1

    spring初探1 关于新建对象,对象依赖的三种方式比较 场景 某个交易的业务组建拆分,为原先的功能模块新写了一个业务组件 使用new. 修改上层代码的对象生成部分( 如果不是面向接口编程,简直就是灾 ...

  3. 关于python中字典的一些总结

    1. 获取字典中的值,但是无异常 当在字典中取值的时候,可以使用如下两种方式: >>> d = {'name':'kel'} >>> d {'name': 'kel ...

  4. 【转载】Python中如何高效实现两个字典合并,三种方法比较。

    本文转载自:http://www.pythoner.com/13.html Python中将两个字典进行合并操作,是一个比较常见的问题.本文将介绍几种实现两个字典合并的方案,并对其进行比较. 对于这个 ...

  5. .hpp文件

    hpp在C++中的含义 以前在开源代码里面遇到过,今天看boost源码的时候又遇到了,故学习一下. hPP,计算机术语,用C/C++语言编写的头文件,通常用来定义数据类型,声明变量.函数.结构和类.而 ...

  6. windows分屏

    一.准备 主机.显示屏A.显示屏B.DVI连接线2根 二.操作步骤 1.使用DVI连接线将显示屏A连接到主机上,开机进入windows系统(演示用的是win 7)(若已连接,请跳到第2步.基本上这一步 ...

  7. 在Spring MVC中使用注解的方式校验RequestParams

    概述   Spring MVC支持Bean Validation,通过这个验证技术,可以通过注解方式,很方便的对输入参数进行验证,之前使用的校验方式,都是基于Bean对象的,但是在@RequestPa ...

  8. iOS tableview 优化总结

    根据网络上的优化方法进行了总括.并未仔细进行语言组织.正在这些优化方法进行学习,见另一篇文章 提高app流畅度 1.cell子控件创建写在 initWithStyle:reuseIdentifier ...

  9. SvUDID实现设备唯一标示

    //SvUDIDTools : https://github.com/smileEvday/SvUDID //将生成的UDID保存到钥匙串中,用户卸载app再重新安装UDID也不会改变. /* 用法1 ...

  10. 深入.Net字符串类型

    .Net的字符串其实还是有很多东西可以写的.但是最近在学习SQL Server,只好先做下最近学习到的一些巧用,妙用之类的东西. 巧用String.Join拼接字串数组,字符串集合为字符串.如果在之前 ...