//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 fileif (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 uncompressedif (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的形式进行初始化就可以,纹理纹理渲染完毕就可以增加到显示队列,当然这里仅仅是先简介下,关于渲染流程等我写完图片的解码部分再回来补充~

未完待续…

转载于:https://www.cnblogs.com/yxwkf/p/5375296.html

cocos2dx的图片载入相关推荐

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

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

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

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

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

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

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

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

  5. 实现将指定图片载入剪贴板并发送至指定QQ群

    距离上一篇如何实现本地唤醒指定QQ群的文章发表已经过去将近一天了,今天要做的就是在上一篇的基础上实现文章标题中的功能. 我先是大费周章的用了一种笨且不稳定的方法实现将图片载入剪贴板:通过命令行调用Wi ...

  6. Android批量图片载入经典系列——使用LruCache、AsyncTask缓存并异步载入图片

    一.问题描写叙述 使用LruCache.AsyncTask实现批量图片的载入并达到下列技术要求 1.从缓存中读取图片,若不在缓存中,则开启异步线程(AsyncTask)载入图片,并放入缓存中 2.及时 ...

  7. Android下将图片载入到内存中

    Android的系统的标准默认每一个应用程序分配的内存是16M.所以来说是很宝贵的,在创建应用的时候要尽可能的去节省内存,可是在载入一些大的文件的时候,比方图片是相当耗内存的,一个1.3M的图片,分辨 ...

  8. android glide图片框架,【Android 进阶】图片载入框架之Glide(示例代码)

    简单介绍 在泰国举行的谷歌开发人员论坛上,谷歌为我们介绍了一个名叫 Glide 的图片载入库,作者是 bumptech.这个库被广泛的运用在 google 的开源项目中,包含 2014 年 googl ...

  9. 1 用python进行OpenCV实战之用OpenCV3实现图片载入、显示和储存

    code 将下面文档存为load_display_save.py #-*- coding:utf-8 -*- from __future__ import print_function #1 impo ...

最新文章

  1. Linux内核探讨-- 第四章
  2. python有道翻译接口-【Python】Python利用有道翻译开发API应用示例
  3. git 撤销刚才的rebase_git rebase 的使用 (用于撤销某次commit)
  4. 互联网造富亲历者讲述:屌丝富了以后
  5. 神奇的css3(2)动画
  6. [USACO12OPEN]Unlocking Block【BFS / 广搜】
  7. 设置UYVY格式YUV为黑色
  8. 项目中的通用查询参数类,它体现了项目架构的大局观
  9. Ubuntu20装Nvidia驱动--中文显示乱码问题
  10. eps如何建立立体白模_EPS 三维测图系统(垂直摄影)快速入门手册.pdf
  11. 10月14号 - 15号 上海 IDC DX 大会
  12. 按键消抖的Verilog实现
  13. hadoop 3.0新特性简单介绍
  14. java斜线_Java中的 \ (反斜线)和正则表达式
  15. MEM/MBA英语基础(02) 句子成分基础
  16. vscode 源代码管理窗口显示空白
  17. 备战2022高考,贺阳衡水一中高级中学高三师生全力以赴
  18. 北航3系 (自动化) 控制科学与工程 保研经历
  19. 依次输入5个数,求其中的最大值并输出
  20. android movie 资源释放,Android 资讯类App项目实战 第四章 电影模块

热门文章

  1. 将本地jar包上传至Nexus
  2. 写的很好!细数 Java 线程池的原理
  3. mysqlbinlog -v与-vv --base64-output 与不加的区别
  4. 罗辑思维首席架构师:Go微服务改造实践
  5. 我的编码习惯 —— API 接口定义
  6. Redis持久化:AOF和RDB
  7. Android --- 怎么样在布局中显示服务器的图片,或者是后台项目中的图片+connect failed: ECONNREFUSED (Connection refused)问题的解决(文章最后)
  8. 浮点数例外 (核心已转储)_15000 字梳理 JVM 的核心知识
  9. java随机数转换_Java获取随机数的3种方法(转)
  10. mysql 数据目录迁移_MySQL数据库数据文件路径迁移步骤