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 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;}//四分之一大小的mipmapwidth = 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;// shadersetGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE));}

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

未完待续…

期待遇上一位撑着油纸伞,结着忧愁丁香一样的姑娘;或者在春暖花开时,

cocos2dx的图片加载

相关文章:

你感兴趣的文章:

标签云: