CCSpriteHole in cocos2d 2.0?

Posted by rakkarage on Game Development See other posts from Game Development or by rakkarage
Published on 2012-10-21T21:52:14Z Indexed on 2012/10/21 23:20 UTC
Read the original article Hit count: 262

Filed under:
|

i was using this cocos2d class CCSpriteHole in cocos2d 1.0 fine...

http://jpsarda.tumblr.com/post/15779708304/new-cocos2d-iphone-extensions-a-progress-bar-and-a

i am trying to convert it to cocos2d 2.0... i got it to compile by changing glVertexPointer to glVertexAttribPointer like in the 2.0 version of CCSpriteScale9 here

http://jpsarda.tumblr.com/post/9162433577/scale9grid-for-cocos2d

and changing contentSizeInPixels_ to contentSize_...

-(id) init {
    if( (self=[super init]) ) {
        opacityModifyRGB_           = YES;
        opacity_                    = 255;
        color_ = colorUnmodified_   = ccWHITE;

        capSize=capSizeInPixels=CGSizeZero; //Not used

        blendFunc_.src = CC_BLEND_SRC;
        blendFunc_.dst = CC_BLEND_DST;

        // update texture (calls updateBlendFunc)
        [self setTexture:nil];

        // default transform anchor
        anchorPoint_ =  ccp(0.5f, 0.5f);

        vertexDataCount=24;
        vertexData = (ccV2F_C4F_T2F*) malloc(vertexDataCount * sizeof(ccV2F_C4F_T2F));

        [self setTextureRectInPixels:CGRectZero untrimmedSize:CGSizeZero];
    }
    return self;
}
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect {
    NSAssert(texture!=nil, @"Invalid texture for sprite");
    // IMPORTANT: [self init] and not [super init];
    if( (self = [self init]) ) {
        [self setTexture:texture];
        [self setTextureRect:rect];
    }
    return self;
}
-(id) initWithTexture:(CCTexture2D*)texture {
    NSAssert(texture!=nil, @"Invalid texture for sprite");

    CGRect rect = CGRectZero;
    rect.size = texture.contentSize;
    return [self initWithTexture:texture rect:rect];
}
-(id) initWithFile:(NSString*)filename {
    NSAssert(filename!=nil, @"Invalid filename for sprite");

    CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage: filename];
    if( texture )
        return [self initWithTexture:texture];

    return nil;
}

+(id)spriteWithFile:(NSString*)f {
    return [[self alloc] initWithFile:f];
}
- (void) dealloc {
    if (vertexData) free(vertexData);
}
-(void) updateColor {
    ccColor4F color4;
    color4.r=(float)color_.r/255.0f;
    color4.g=(float)color_.g/255.0f;
    color4.b=(float)color_.b/255.0f;
    color4.a=(float)opacity_/255.0f;

    for (int i=0; i<vertexDataCount; i++) {
        vertexData[i].colors=color4;
    }
}
-(void)updateTextureCoords:(CGRect)rect {
    CCTexture2D *tex = texture_;
    if(!tex)
        return;

    float atlasWidth = (float)tex.pixelsWide;
    float atlasHeight = (float)tex.pixelsHigh;

    float left,right,top,bottom;

    left    = rect.origin.x/atlasWidth;
    right   = left + rect.size.width/atlasWidth;
    top     = rect.origin.y/atlasHeight;
    bottom  = top + rect.size.height/atlasHeight;

    //
    //  |/|/|/|
    //

    CGSize capTexCoordsSize=CGSizeMake(capSizeInPixels.width/atlasWidth, capSizeInPixels.height/atlasHeight);

    // From left to right

    //Top band
    // Left
    vertexData[0].texCoords=(ccTex2F){left,top};
    vertexData[1].texCoords=(ccTex2F){left,top+capTexCoordsSize.height};
    vertexData[2].texCoords=(ccTex2F){left+capTexCoordsSize.width,top};
    vertexData[3].texCoords=(ccTex2F){left+capTexCoordsSize.width,top+capTexCoordsSize.height};
    // Center
    vertexData[4].texCoords=(ccTex2F){right-capTexCoordsSize.width,top};
    vertexData[5].texCoords=(ccTex2F){right-capTexCoordsSize.width,top+capTexCoordsSize.height};
    // Right
    vertexData[6].texCoords=(ccTex2F){right,top};
    vertexData[7].texCoords=(ccTex2F){right,top+capTexCoordsSize.height};

    //Center band
    // Left
    vertexData[8].texCoords=(ccTex2F){left,bottom-capTexCoordsSize.height};
    vertexData[9].texCoords=(ccTex2F){left,top+capTexCoordsSize.height};
    vertexData[10].texCoords=(ccTex2F){left+capTexCoordsSize.width,bottom-capTexCoordsSize.height};
    vertexData[11].texCoords=(ccTex2F){left+capTexCoordsSize.width,top+capTexCoordsSize.height};
    // Center
    vertexData[12].texCoords=(ccTex2F){right-capTexCoordsSize.width,bottom-capTexCoordsSize.height};
    vertexData[13].texCoords=(ccTex2F){right-capTexCoordsSize.width,top+capTexCoordsSize.height};
    // Right
    vertexData[14].texCoords=(ccTex2F){right,bottom-capTexCoordsSize.height};
    vertexData[15].texCoords=(ccTex2F){right,top+capTexCoordsSize.height};

    //Bottom band
    //Left
    vertexData[16].texCoords=(ccTex2F){left,bottom};
    vertexData[17].texCoords=(ccTex2F){left,bottom-capTexCoordsSize.height};
    vertexData[18].texCoords=(ccTex2F){left+capTexCoordsSize.width,bottom};
    vertexData[19].texCoords=(ccTex2F){left+capTexCoordsSize.width,bottom-capTexCoordsSize.height};
    // Center
    vertexData[20].texCoords=(ccTex2F){right-capTexCoordsSize.width,bottom};
    vertexData[21].texCoords=(ccTex2F){right-capTexCoordsSize.width,bottom-capTexCoordsSize.height};
    // Right
    vertexData[22].texCoords=(ccTex2F){right,bottom};
    vertexData[23].texCoords=(ccTex2F){right,bottom-capTexCoordsSize.height};
}
-(void) updateVertices {
    float left=0; //-spriteSizeInPixels.width*0.5f;
    float right=left+contentSize_.width;
    float bottom=0; //-spriteSizeInPixels.height*0.5f;
    float top=bottom+contentSize_.height;

    float holeLeft=holeRect.origin.x*CC_CONTENT_SCALE_FACTOR();
    float holeRight=holeLeft+holeRect.size.width*CC_CONTENT_SCALE_FACTOR();

    float holeBottom=holeRect.origin.y*CC_CONTENT_SCALE_FACTOR();
    float holeTop=holeBottom+holeRect.size.height*CC_CONTENT_SCALE_FACTOR();

    //
    //  |/|/|/|
    //

    // From left to right

    //Top band
    // Left
    vertexData[0].vertices=(ccVertex2F){left,top};
    vertexData[1].vertices=(ccVertex2F){left,holeTop};
    vertexData[2].vertices=(ccVertex2F){holeLeft,top};
    vertexData[3].vertices=(ccVertex2F){holeLeft,holeTop};
    // Center
    vertexData[4].vertices=(ccVertex2F){holeRight,top};
    vertexData[5].vertices=(ccVertex2F){holeRight,holeTop};
    // Right
    vertexData[6].vertices=(ccVertex2F){right,top};
    vertexData[7].vertices=(ccVertex2F){right,holeTop};

    //Center band
    // Left
    vertexData[8].vertices=(ccVertex2F){left,holeBottom};
    vertexData[9].vertices=(ccVertex2F){left,holeTop};
    vertexData[10].vertices=(ccVertex2F){holeLeft,holeBottom};
    vertexData[11].vertices=(ccVertex2F){holeLeft,holeTop};
    // Center
    vertexData[12].vertices=(ccVertex2F){holeRight,holeBottom};
    vertexData[13].vertices=(ccVertex2F){holeRight,holeTop};
    // Right
    vertexData[14].vertices=(ccVertex2F){right,holeBottom};
    vertexData[15].vertices=(ccVertex2F){right,holeTop};

    //Bottom band
    //Left
    vertexData[16].vertices=(ccVertex2F){left,bottom};
    vertexData[17].vertices=(ccVertex2F){left,holeBottom};
    vertexData[18].vertices=(ccVertex2F){holeLeft,bottom};
    vertexData[19].vertices=(ccVertex2F){holeLeft,holeBottom};
    // Center
    vertexData[20].vertices=(ccVertex2F){holeRight,bottom};
    vertexData[21].vertices=(ccVertex2F){holeRight,holeBottom};
    // Right
    vertexData[22].vertices=(ccVertex2F){right,bottom};
    vertexData[23].vertices=(ccVertex2F){right,holeBottom};
}

-(void) setHole:(CGRect)r inRect:(CGRect)totalSurface {
    holeRect=r;
    self.contentSize=totalSurface.size;
    holeRect.origin=ccpSub(holeRect.origin,totalSurface.origin);
    CGPoint holeCenter=ccp(holeRect.origin.x+holeRect.size.width*0.5f,holeRect.origin.y+holeRect.size.height*0.5f);
    self.anchorPoint=ccp(holeCenter.x/contentSize_.width,holeCenter.y/contentSize_.height);

    //[self updateTextureCoords:rectInPixels_];
    [self updateVertices];
    [self updateColor];
}
-(void) draw {
    BOOL newBlend = NO;
    if( blendFunc_.src != CC_BLEND_SRC || blendFunc_.dst != CC_BLEND_DST ) {
        newBlend = YES;
        glBlendFunc( blendFunc_.src, blendFunc_.dst );
    }

    glBindTexture(GL_TEXTURE_2D, [texture_ name]);

    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[0].vertices);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[0].texCoords);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[0].colors);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);

    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[8].vertices);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[8].texCoords);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[8].colors);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);

    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[16].vertices);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[16].texCoords);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, sizeof(ccV2F_C4F_T2F), &vertexData[16].colors);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);

    if( newBlend )
        glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);

}

-(void)setTextureRectInPixels:(CGRect)rect untrimmedSize:(CGSize)untrimmedSize {
    rectInPixels_ = rect;
    rect_ = CC_RECT_PIXELS_TO_POINTS( rect );

    //[self setContentSizeInPixels:untrimmedSize];
    [self updateTextureCoords:rectInPixels_];   
}
-(void)setTextureRect:(CGRect)rect {
    CGRect rectInPixels = CC_RECT_POINTS_TO_PIXELS( rect );
    [self setTextureRectInPixels:rectInPixels untrimmedSize:rectInPixels.size];
}


//
// RGBA protocol
//
#pragma mark CCSpriteHole - RGBA protocol
-(GLubyte) opacity {
    return opacity_;
}

-(void) setOpacity:(GLubyte) anOpacity {
    opacity_            = anOpacity;

    // special opacity for premultiplied textures
    if( opacityModifyRGB_ )
        [self setColor: (opacityModifyRGB_ ? colorUnmodified_ : color_ )];

    [self updateColor];
}

- (ccColor3B) color {
    if(opacityModifyRGB_){
        return colorUnmodified_;
    }
    return color_;
}

-(void) setColor:(ccColor3B)color3 {
    color_ = colorUnmodified_ = color3;

    if( opacityModifyRGB_ ){
        color_.r = color3.r * opacity_/255;
        color_.g = color3.g * opacity_/255;
        color_.b = color3.b * opacity_/255;
    }

    [self updateColor];
}

-(void) setOpacityModifyRGB:(BOOL)modify {
    ccColor3B oldColor  = self.color;
    opacityModifyRGB_   = modify;
    self.color          = oldColor;
}

-(BOOL) doesOpacityModifyRGB {
    return opacityModifyRGB_;
}


#pragma mark CCSpriteHole - CocosNodeTexture protocol

-(void) updateBlendFunc {
    if( !texture_ || ! [texture_ hasPremultipliedAlpha] ) {
        blendFunc_.src = GL_SRC_ALPHA;
        blendFunc_.dst = GL_ONE_MINUS_SRC_ALPHA;
        [self setOpacityModifyRGB:NO];
    } else {
        blendFunc_.src = CC_BLEND_SRC;
        blendFunc_.dst = CC_BLEND_DST;
        [self setOpacityModifyRGB:YES];
    }
}

-(void) setTexture:(CCTexture2D*)texture {  
    // accept texture==nil as argument
    NSAssert( !texture || [texture isKindOfClass:[CCTexture2D class]], @"setTexture expects a CCTexture2D. Invalid argument");

    texture_ = texture;

    [self updateBlendFunc];
}

-(CCTexture2D*) texture {
    return texture_;
}
@end

but now positioning and scaling seem to not work? and it starts in the wrong position... but changing the opacity still works.

so i was wondering if anyone can see why my 2.0 version is not working? or if maybe there is a better way to do a sprite hole with cocos2d/opengl 2.0? shaders?

thanks

© Game Development or respective owner

Related posts about cocos2d-iphone

Related posts about cocos2d