展会信息港展会大全

cocos2dx的图片加载,cocos2dx图片加载
来源:互联网   发布日期:2015-09-28 15:26:54   浏览:1714次  

导读: cocos2dx的图片加载,cocos2dx图片加载 //data: 图片文件数据 dataLen: 文件长度 bool Image::initWithImageData(co...

cocos2dx的图片加载,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的形式进行初始化即可,纹理纹理渲染完成即可加入到显示队列,当然这里只是先简单介绍下,关于渲染流程等我写完图片的解码部分再回来补充~

未完待续…

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

http://www.bkjia.com/Androidjc/1034474.htmlwww.bkjia.comtruehttp://www.bkjia.com/Androidjc/1034474.htmlTechArticlecocos2dx的图片加载,cocos2dx图片加载 //data: 图片文件数据 dataLen: 文件长度bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen){ bool ret...

赞助本站

人工智能实验室

相关热词: android开发 应用开发

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港