JNIEXPORT void JNICALL Java_org_cocos2dx_lib_CCImage_1richlabel_nativeGetSpriteFrameInfo (JNIEnv * env, jclass clazz, jstring jPlist, jstring jAtlas, jstring jImageName, jobject jFrame) { // get c string const char* plist = (const char*)env->GetStringUTFChars(jPlist, NULL); const char* atlas = (const char*)env->GetStringUTFChars(jAtlas, NULL); const char* imageName = (const char*)env->GetStringUTFChars(jImageName, NULL); // get sprite frame CLBitmapDC& bitmapDC = CLBitmapDC::sharedCLBitmapDC(); CCSpriteFrameCache* fc = CCSpriteFrameCache::sharedSpriteFrameCache(); if(!fc->spriteFrameByName(imageName)) { if(bitmapDC.m_decryptFunc) { // load encryptd data unsigned long len; char* data = (char*)CCFileUtils::sharedFileUtils()->getFileData(atlas, "rb", &len); // create texture int decLen; const char* dec = (*bitmapDC.m_decryptFunc)(data, (int)len, &decLen); CCImage* image = new CCImage(); image->initWithImageData((void*)dec, decLen); image->autorelease(); CCTexture2D* tex = CCTextureCache::sharedTextureCache()->addUIImage(image, atlas); // add fc->addSpriteFramesWithFile(plist, tex); // free if(data != dec) free((void*)dec); free(data); } else { fc->addSpriteFramesWithFile(plist, atlas); } } CCSpriteFrame* frame = fc->spriteFrameByName(imageName); // get java frame info jclass frameClass = env->FindClass("org/cocos2dx/lib/CCImage_richlabel$AtlasFrame"); jfieldID fid_x = env->GetFieldID(frameClass, "x", "I"); jfieldID fid_y = env->GetFieldID(frameClass, "y", "I"); jfieldID fid_w = env->GetFieldID(frameClass, "w", "I"); jfieldID fid_h = env->GetFieldID(frameClass, "h", "I"); jfieldID fid_offsetX = env->GetFieldID(frameClass, "offsetX", "I"); jfieldID fid_offsetY = env->GetFieldID(frameClass, "offsetY", "I"); jfieldID fid_sourceWidth = env->GetFieldID(frameClass, "sourceWidth", "I"); jfieldID fid_sourceHeight = env->GetFieldID(frameClass, "sourceHeight", "I"); jfieldID fid_rotated = env->GetFieldID(frameClass, "rotated", "Z"); // copy frame info to java object const CCSize& sourceSize = frame->getOriginalSizeInPixels(); bool rotated = frame->isRotated(); const CCRect& frameRect = frame->getRectInPixels(); const CCPoint& offset = frame->getOffsetInPixels(); env->SetIntField(jFrame, fid_x, (int)frameRect.origin.x); env->SetIntField(jFrame, fid_y, (int)frameRect.origin.y); env->SetIntField(jFrame, fid_w, (int)frameRect.size.width); env->SetIntField(jFrame, fid_h, (int)frameRect.size.height); env->SetIntField(jFrame, fid_offsetX, (int)offset.x); env->SetIntField(jFrame, fid_offsetY, (int)offset.y); env->SetIntField(jFrame, fid_sourceWidth, (int)sourceSize.width); env->SetIntField(jFrame, fid_sourceHeight, (int)sourceSize.height); env->SetBooleanField(jFrame, fid_rotated, rotated); // release env->DeleteLocalRef(frameClass); env->ReleaseStringUTFChars(jPlist, plist); env->ReleaseStringUTFChars(jAtlas, atlas); env->ReleaseStringUTFChars(jImageName, imageName); }
//the frames should have the same size in texture so shouldn't trim the frame //I wish this limit will be removed in next moment void CCParticleSystemFrameQuad::setTextureWithFrames(CCTexture2D* texture, CCArray* frames) { // Only update the texture if is different from the current one if( !m_pTexture || texture->getName() != m_pTexture->getName() ) { CCParticleSystem::setTexture(texture); } clearFrameSetting(); unsigned int totalFrames = frames->count(); m_pFrameQuads = new float *[totalFrames]; for(unsigned int i=0; i<totalFrames;i++){ CCSpriteFrame *frame = dynamic_cast<CCSpriteFrame*>(frames->objectAtIndex(i)); if(frame==NULL || frame->getTexture()->getName()!= m_pTexture->getName()) continue; CCRect rect = frame->getRect(); float* m_sQuad = new float[4]; m_pFrameQuads[m_uTotalFrames] = m_sQuad; m_uTotalFrames++; float atlasWidth = (float)m_pTexture->getPixelsWide(); float atlasHeight = (float)m_pTexture->getPixelsHigh(); float left, right, top, bottom; if (frame->isRotated()) { #if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL left = (2*rect.origin.x+1)/(2*atlasWidth); right = left+(rect.size.height*2-2)/(2*atlasWidth); top = (2*rect.origin.y+1)/(2*atlasHeight); bottom = top+(rect.size.width*2-2)/(2*atlasHeight); #else left = rect.origin.x/atlasWidth; right = (rect.origin.x+rect.size.height) / atlasWidth; top = rect.origin.y/atlasHeight; bottom = (rect.origin.y+rect.size.width) / atlasHeight; #endif // CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL } else { #if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL left = (2*rect.origin.x+1)/(2*atlasWidth); right = left + (rect.size.width*2-2)/(2*atlasWidth); top = (2*rect.origin.y+1)/(2*atlasHeight); bottom = top + (rect.size.height*2-2)/(2*atlasHeight); #else left = rect.origin.x/atlasWidth; right = (rect.origin.x + rect.size.width) / atlasWidth; top = rect.origin.y/atlasHeight; bottom = (rect.origin.y + rect.size.height) / atlasHeight; #endif // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL } m_sQuad[0] = left; m_sQuad[1] = right; m_sQuad[2] = top; m_sQuad[3] = bottom; } GLfloat wide = (GLfloat)m_pTexture->getPixelsWide(); GLfloat high = (GLfloat)m_pTexture->getPixelsHigh(); ccV3F_C4B_T2F_Quad *quads = NULL; unsigned int start = 0, end = 0; if (m_pBatchNode) { quads = m_pBatchNode->getTextureAtlas()->getQuads(); start = m_uAtlasIndex; end = m_uAtlasIndex + m_uTotalParticles; } else { quads = m_pQuads; start = 0; end = m_uTotalParticles; } for(unsigned int i=start; i<end; i++) { int fid = rand()%m_uTotalFrames; float* m_sQuad = m_pFrameQuads[fid]; // bottom-left vertex: quads[i].bl.texCoords.u = m_sQuad[0]; quads[i].bl.texCoords.v = m_sQuad[3]; // bottom-right vertex: quads[i].br.texCoords.u = m_sQuad[1]; quads[i].br.texCoords.v = m_sQuad[3]; // top-left vertex: quads[i].tl.texCoords.u = m_sQuad[0]; quads[i].tl.texCoords.v = m_sQuad[2]; // top-right vertex: quads[i].tr.texCoords.u = m_sQuad[1]; quads[i].tr.texCoords.v = m_sQuad[2]; } }