bool EraserSprite::getEraserOk() { m_bEraserOk = false; CCImage* image = new CCImage(); image = m_pRTex->newCCImage(true); int m = 3; if (image->hasAlpha()) { m = 4; } unsigned char *data_= image->getData(); int x = 0, y = 0; /// 这里要一点,即Opengl下,其中心点坐标在左上角 for (x = 0; x < spriteSize.width; ++x) { for (y = 0 ; y < spriteSize.height; ++y) { unsigned char *pixel = data_ + (x + y * image->getWidth()) * m; // You can see/change pixels' RGBA value(0-255) here ! unsigned int r = (unsigned int)*pixel; unsigned int g = (unsigned int)*(pixel + 1); unsigned int b = (unsigned int)*(pixel + 2) ; unsigned int a = (unsigned int)*(pixel + 3); if (r != 0 && g != 0 && b != 0 && a != 0) { m_bEraserOk = false; break; } } if (spriteSize.height != y) { break; } } if (x == spriteSize.width && y == spriteSize.height) { m_bEraserOk = true; } delete image; return this->m_bEraserOk; }
CCSprite* GameUtil::fitSprite(CCSprite* pSprite) { // 원본의 원래위치 백업 CCPoint ptOrg = pSprite->getPosition(); // 원본 스프라이트 위치를 Center로 설정 pSprite->setPosition(ccp(pSprite->getContentSize().width/2, pSprite->getContentSize().height/2)); // CCImage를 만들기 위해서 RenderTexture 생성 CCRenderTexture * rtNew = CCRenderTexture::create((int)pSprite->getContentSize().width, (int)pSprite->getContentSize().height); rtNew->begin(); pSprite->visit(); rtNew->end(); // CCImage 생성 CCImage *pImage = rtNew->newCCImage(); int width = pImage->getWidth(); int height = pImage->getHeight(); int bytesPerComponent = pImage->getBitsPerComponent() / 8; // 기본값 8bit bool bAlpha = pImage->hasAlpha(); int nRGBA = 4; if (!bAlpha) nRGBA = 3; // 픽셀 데이터 (RGBA 순서, 각각 bytesPerComponent 크기만큼) unsigned char* pData = pImage->getData(); int index = 0; int l=5000; // left int r=0; // right int t=0; // top int b=5000; // bottom unsigned char* ptr; for (int x=0; x<width; x++) { for (int y=0; y<height; y++) { index = (y*width + x) * bytesPerComponent * nRGBA; ptr = pData + index; if (0 != ptr[0] || 0 != ptr[1] || 0 != ptr[2]) { l = min(l, x); // left r = max(r, x); // right t = max(t, y); // top b = min(b, y); // bottom } } } // 좌표계 보정 (픽셀데이터는 좌상단을 0,0 으로 하기때문에) int b2 = pSprite->getContentSize().height - t; int t2 = pSprite->getContentSize().height - b; CC_SAFE_DELETE(pImage); // 원래 위치로 설정 pSprite->setPosition(ptOrg); // 스프라이트로 생성 CCSprite* pCrop = CCSprite::createWithTexture(pSprite->getTexture()); pCrop->setTextureRect(CCRect(l, b2, r-l, t2-b2)); pCrop->setPosition(ccp(pCrop->getContentSize().width/2, pCrop->getContentSize().height/2)); pCrop->setFlipY(true); // 크기에 꼭 맞는 새로운 RenderTexture를 만든다. CCRenderTexture * rtNew2 = CCRenderTexture::create(r-l, t2-b2); rtNew2->begin(); pCrop->visit(); rtNew2->end(); // 크기에 꼭 맞는 새로운 Sprite를 만든다. CCSprite *retSprite = CCSprite::createWithTexture(rtNew2->getSprite()->getTexture()); retSprite->setFlipY(true); rtNew2->release(); pCrop->release(); return retSprite; }
CCRect GameUtil::getFitRect(CCSprite* pSprite) { // 원본의 원래위치 백업 CCPoint ptOrg = pSprite->getPosition(); // 원본 스프라이트 위치를 Center로 설정 pSprite->setPosition(ccp(pSprite->getContentSize().width/2, pSprite->getContentSize().height/2)); // CCImage를 만들기 위해서 RenderTexture 생성 CCRenderTexture * rtNew = CCRenderTexture::create((int)pSprite->getContentSize().width, (int)pSprite->getContentSize().height); rtNew->begin(); pSprite->visit(); rtNew->end(); // CCImage 생성 CCImage *pImage = rtNew->newCCImage(); int width = pImage->getWidth(); int height = pImage->getHeight(); int bytesPerComponent = pImage->getBitsPerComponent() / 8; // 기본값 8bit bool bAlpha = pImage->hasAlpha(); int nRGBA = 4; if (!bAlpha) nRGBA = 3; // 픽셀 데이터 (RGBA 순서, 각각 bytesPerComponent 크기만큼) unsigned char* pData = pImage->getData(); int index = 0; int l=5000; // left int r=0; // right int t=5000; // top int b=0; // bottom unsigned char* ptr; for (int x=0; x<width; x++) { for (int y=0; y<height; y++) { index = (y*width + x) * bytesPerComponent * nRGBA; ptr = pData + index; if (0 != ptr[0] || 0 != ptr[1] || 0 != ptr[2]) { l = min(l, x); // left r = max(r, x); // right t = min(t, y); // top b = max(b, y); // bottpm } } } // 좌표계 보정 (픽셀데이터는 좌상단을 0,0 으로 하기때문에) int b2 = pSprite->getContentSize().height - t; int t2 = pSprite->getContentSize().height - b; CC_SAFE_DELETE(pImage); // 원래 위치로 설정 pSprite->setPosition(ptOrg); CCRect rc; rc.origin.x = l; rc.origin.y = t2; rc.size.width = r - l; rc.size.height = b2 - t2; return rc; }
static void* loadImage(void* data) { AsyncStruct *pAsyncStruct = NULL; while (true) { // create autorelease pool for iOS CCThread thread; thread.createAutoreleasePool(); // wait for rendering thread to ask for loading if s_pAsyncStructQueue is empty int semWaitRet = sem_wait(s_pSem); if( semWaitRet < 0 ) { CCLOG( "CCTextureCache async thread semaphore error: %s\n", strerror( errno ) ); break; } std::queue<AsyncStruct*>* pQueue = s_pAsyncStructQueue; pthread_mutex_lock(&s_asyncStructQueueMutex);// get async struct from queue if (pQueue->empty()) { pthread_mutex_unlock(&s_asyncStructQueueMutex); if (need_quit) break; else continue; } else { pAsyncStruct = pQueue->front(); pQueue->pop(); pthread_mutex_unlock(&s_asyncStructQueueMutex); } const char* filename = pAsyncStruct->filename.c_str(); // compute image type CCImage::EImageFormat imageType = CCImage::computeImageFormatType(pAsyncStruct->filename); if (imageType == CCImage::kFmtUnKnown) { CCLOG("unsupported format %s",filename); delete pAsyncStruct; continue; } // generate image CCImage* pImage = pAsyncStruct->image; if (pImage && !pImage->initWithImageFileThreadSafe(filename, imageType)) { pAsyncStruct->image = NULL; CC_SAFE_RELEASE(pImage); CCLOG("can not load %s", filename); continue; } unsigned char* tempData = CCImage::convertToRequiredFormat(pImage); if (tempData != pImage->getData()) { CCSize size = CCSizeMake(pImage->getWidth(), pImage->getHeight()); size_t bpp = pImage->getBitsPerComponent(); CCTexture2DPixelFormat pixelFormat = pImage->hasAlpha() ? CCTexture2D::getDefaultAlphaPixelFormat() : (bpp >= 8 ? kCCTexture2DPixelFormat_RGB888 : kCCTexture2DPixelFormat_RGB565); pAsyncStruct->image = NULL; CC_SAFE_RELEASE(pImage); pAsyncStruct->data = tempData; pAsyncStruct->size = size; pAsyncStruct->pixelFormat = pixelFormat; } // generate image info ImageInfo* pImageInfo = new ImageInfo(); pImageInfo->asyncStruct = pAsyncStruct; pImageInfo->imageType = imageType; // put the image info into the queue pthread_mutex_lock(&s_ImageInfoMutex); s_pImageQueue->push(pImageInfo); pthread_mutex_unlock(&s_ImageInfoMutex); } if( s_pSem != NULL ) { #if CC_ASYNC_TEXTURE_CACHE_USE_NAMED_SEMAPHORE sem_unlink(CC_ASYNC_TEXTURE_CACHE_SEMAPHORE); sem_close(s_pSem); #else sem_destroy(s_pSem); #endif s_pSem = NULL; delete s_pAsyncStructQueue; delete s_pImageQueue; } return 0; }