cocos2dx的图片载入
//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的图片载入的更多相关文章
- Cocos2d-x 3.0心得(01)-图片载入与混合模式
近期開始用cocos2dx 3.0做东西,略有心(cao)得(dian),略微作下记录吧. v3.0相对v2.2来说,最引人注意的,应该是对触摸层级的优化.和lambda回调函数的引入(嗯嗯.不枉我改 ...
- cocos2d-x 获取图片的某像素点的RGBA颜色 -转
cocos2d-x 获取图片的某像素点的RGBA颜色 原文:http://www.cnblogs.com/jaoye/archive/2013/02/19/2916501.html 没做过 太多的图 ...
- Android图片载入框架最全解析(一),Glide的基本使用方法
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53759439 本文同步发表于我的微信公众号.扫一扫文章底部的二维码或在微信搜索 郭 ...
- Android批量图片载入经典系列——afinal框架实现图片的异步缓存载入
一.问题描写叙述 在之前的系列文章中,我们使用了Volley和Xutil框架实现图片的缓存载入,接下来我们再介绍一下afinal 框架的使用. Afinal 是一个android的http框架.sql ...
- 一个方便的图片载入框架——ImageViewEx
我的博客:http://mrfufufu.github.io/ 一.前言 近期在整理项目中的一些代码,以备即将开展的新项目中使用,刚刚整理到一个图片载入的 lib.用起来很的简单,和 picasso ...
- Android Handler 异步消息处理机制的妙用 创建强大的图片载入类
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号: ...
- Android图片载入缓存框架Glide
Glide开源框架是Google推荐的图片载入和缓框架,其在Github上的开源地址是:https://github.com/bumptech/glide 当然一个Google推荐的框架肯定就是Vol ...
- 安卓图片载入之使用universalimageloader载入圆形圆角图片
前言 话说这universalimageloader载入图片对搞过2年安卓程序都是用烂了再熟悉只是了.就是安卓新手也是百度就会有一大堆东西出来,今天为什么这里还要讲使用universalimagelo ...
- Universal-Image-Loader(UIL)图片载入框架使用简介
这个也是近期项目中使用到的第三方图片载入框架.在这里也自己总结一下,简单的介绍一些使用的方式. UIL图片载入框架特点 简单介绍: 项目地址:https://github.com/nostra13/A ...
随机推荐
- LR之录制SQL脚本
1.选择协议 ①MS SQL serve ②ODBC 一般情况下选ODBC 2.录制步骤
- static_cast .xml
pre{ line-height:1; color:#1e1e1e; background-color:#d2d2d2; font-size:16px;}.sysFunc{color:#627cf6; ...
- css3 --- 翻页动画 --- javascript --- 3d --- 准备
用css3和javascript做一个翻页动画<知识准备部分> 如有更多疑问请参照:http://www.imooc.com/learn/77 这是用css3的-webkit-transi ...
- Swift 脚本(运行时带参数)
#!/usr/bin/env xcrun swift import Foundation let args = Process.arguments print("Arg:\(args)&qu ...
- 《Java数据结构与算法》笔记-CH4-5不带计数字段的循环队列
第四章涉及三种数据存储类型:栈,队列,优先级队列 1.概括:他们比数组和其他数据存储结构更为抽象,主要通过接口对栈,队列和优先级队列进行定义.这些 接口表明通过他们可以完成的操作,而他们的主要实现机制 ...
- 谈FTP服务器攻击技术及其展望 (修改中)
欢迎大家给我投票: http://2010blog.51cto.com/350944 请看下篇:谈FTP服务器攻击技术及其展望 (下) 全文完http://chengua ...
- [转]float,double和decimal类型
float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位) double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E308(15个有 ...
- Apache Spark的部署环境的小记
Spark的单机版便于测试,同时通过SSH用Spark的内置部署脚本搭建Spark集群,使用Mesos.Yarn或者Chef来部署Spark.对于Spark在云环境中的部署,比如在EC2(基本环境和E ...
- HD2025查找最大元素
查找最大元素 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- access检测表没有的字段,添加之
#region 检测是否存在STATE字段,没有就添加 /// <summary> /// 检测是否存在STATE字段,没有就添加 /// </summary> /// < ...