原文請猛戳:
http://galoisplusplus.coding....git
以前曾經在cocos2d-x V3.x不規則按鈕探討過在cocos2d-x 3.x版本實現不規則按鈕的方法,後來本渣又琢磨了下仿照RenderTexture類調用OpenGL ES API來獲取圖片像素信息的方式。這種方式因爲按鈕圖片的Texture已在內存中,且不須要解析圖片文件格式,所以相比以前用Image::initWithImageFile仍是要快一些的。github
重寫的loadNormalTransparentInfo
函數以下:ide
void IrregularButton::loadNormalTransparentInfo() { #ifdef DEBUG auto start = std::chrono::steady_clock::now(); #endif Sprite* normalRenderer = static_cast<Sprite*>(_buttonNormalRenderer); auto normalTexture = normalRenderer->getTexture(); const Size& s = normalTexture->getContentSizeInPixels(); int savedBufferWidth = (int)s.width; int savedBufferHeight = (int)s.height; GLubyte *buffer = nullptr; // the FBO which cocos2dx used is not window-system-provided (non-zero id) GLint oldFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO); GLuint framebuffer; glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glBindTexture(GL_TEXTURE_2D, normalTexture->getName()); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, savedBufferWidth, savedBufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, normalTexture->getName(), 0); CCASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Could not attach texture to framebuffer"); buffer = new (std::nothrow) GLubyte[savedBufferWidth * savedBufferHeight * 4]; glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, savedBufferWidth, savedBufferHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glBindFramebuffer(GL_FRAMEBUFFER, oldFBO); auto dataLen = savedBufferWidth * savedBufferHeight * 4; if (normalTransparent_ != nullptr) { delete[] normalTransparent_; } normalImageWidth_ = savedBufferWidth; normalImageHeight_ = savedBufferHeight; normalTransparent_ = new bool[dataLen / (sizeof(unsigned char) * 4)]; for (auto i = 0; i < normalImageHeight_; i++) { for (auto j = 0; j < normalImageWidth_; j++) { normalTransparent_[i * normalImageWidth_ + j] = (buffer[(i * normalImageWidth_ + j) * 4 + 3] == 0); } } CC_SAFE_DELETE_ARRAY(buffer); #ifdef DEBUG auto end = std::chrono::steady_clock::now(); auto totalTime = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); printf("load from memory: %lld ms\n", totalTime.count()); #endif }
完整代碼請參考:
cocos2d-x-irregular-button函數