通过学习CCSpriteFrameCache和CCTextureCache,作者大致了解了底层精灵帧和纹理的管理,这里备份下纹理的内部实现。
CONTENTS
构造流程:
CCSpriteFrame需要CCTexture,CCTexture需要CCImage。
CCSprite需要CCTexture和CCSpriteFrame。
CCSpriteFrame较简单,这里就先省略了。
CCSprite需要后续统一分析。
CCImage分析:
分享个大神的blog:
【 http://blog.csdn.net/honghaier/article/details/8032434 】
CCTexture2D代码框架:
CCTexture2D的代码较复杂,涉及到了opengl的东西,作者也晕了,这里就简单的备份下最简单的调用流程。
bool CCTexture2D::initWithImage(CCImage *uiImage) { 。。。。。 。。。。。 return initPremultipliedATextureWithImage(uiImage, imageWidth, imageHeight); } bool CCTexture2D::initPremultipliedATextureWithImage(CCImage *image, unsigned int width, unsigned int height) { 。。。。。 。。。。。 initWithData(tempData, pixelFormat, width, height, imageSize); if (tempData != image->getData()) { delete [] tempData; } m_bHasPremultipliedAlpha = image->isPremultipliedAlpha(); return true; } bool CCTexture2D::initWithData(const void *data, CCTexture2DPixelFormat pixelFormat, unsigned int pixelsWide, unsigned int pixelsHigh, const CCSize& contentSize) { unsigned int bitsPerPixel; //Hack: bitsPerPixelForFormat returns wrong number for RGB_888 textures. See function. if(pixelFormat == kCCTexture2DPixelFormat_RGB888) { bitsPerPixel = 24; } else { bitsPerPixel = bitsPerPixelForFormat(pixelFormat); } unsigned int bytesPerRow = pixelsWide * bitsPerPixel / 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); } glGenTextures(1, &m_uName); ccGLBindTexture2D(m_uName); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); // Specify OpenGL texture image switch(pixelFormat) { case kCCTexture2DPixelFormat_RGBA8888: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break; case kCCTexture2DPixelFormat_RGB888: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, GL_RGB, GL_UNSIGNED_BYTE, data); break; case kCCTexture2DPixelFormat_RGBA4444: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); break; case kCCTexture2DPixelFormat_RGB5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, data); break; case kCCTexture2DPixelFormat_RGB565: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); break; case kCCTexture2DPixelFormat_AI88: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data); break; case kCCTexture2DPixelFormat_A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); break; case kCCTexture2DPixelFormat_I8: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, (GLsizei)pixelsWide, (GLsizei)pixelsHigh, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); break; default: CCAssert(0, "NSInternalInconsistencyException"); } m_tContentSize = contentSize; m_uPixelsWide = pixelsWide; m_uPixelsHigh = pixelsHigh; m_ePixelFormat = pixelFormat; m_fMaxS = contentSize.width / (float)(pixelsWide); m_fMaxT = contentSize.height / (float)(pixelsHigh); m_bHasPremultipliedAlpha = false; m_bHasMipmaps = false; setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTexture)); return true; }
CCSprite代码框架:
void CCSprite::setTexture(CCTexture2D *texture) { 。。。。。 。。。。。 m_pobTexture = texture; 。。。。。 。。。。。 } void CCSprite::draw(void) { 。。。。。 ccGLBindTexture2D( m_pobTexture->getName() ); ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex ); 。。。。。 }
发表评论