Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have read this tutorial about how to mask sprites using Cocos2D 2.0. http://www.raywenderlich.com/4428/how-to-mask-a-sprite-with-cocos2d-2-0

But the author talks about OpenGL ES textures and vertices as they were common knowledge. My knowledge about OpenGl is zero raised to infinity.

All I want is to use a rectangle to mask a sprite to it. How I would do in Photoshop using a rectangle as mask (yes, I want to clip a sprite to the rectangle bounds and no, I do not want to use the ClippingNode solution, that do not works for animation/scaling etc.).

So, can you guys translate the klingon language used in this tutorial and tell how a solid rectangle can be used to mask a sprite in Cocos2D?

I am desperate, as my username states. I am searching this for a week and have tried several solutions without satisfactory results. Please help me.

Thanks!

share|improve this question

1 Answer 1

Like you, I'm not very comfortable with OpenGL. Unlike you this tuto helped me, failing to fully understand, to create one component for one of my project. So I'll try to explain it to you as clearly as I can.

The first thing is that you don't have to worry about the mask's shader. It is just a litle "program" which describe the execution pipeline to produce the mask. There is already wrote and it works (cf: Mask.fsh). Just put it into your project.

Then create and init the mask which will be put as a texture, and associate it to the shader:

- (id)initWithFile:(NSString *)file 
{
    self = [super initWithFile:file];
    if (self) {

        // Create your rectangle mask
        _maskTexture = [[[CCTextureCache sharedTextureCache] addImage:@"CalendarMask.png"] retain];

        // Create and init the shader
        self.shaderProgram = 
        [[[GLProgram alloc] 
          initWithVertexShaderFilename:@"Shaders/PositionTextureColor.vert"
          fragmentShaderFilename:@"Mask.frag"] autorelease];
        [shaderProgram_ addAttribute:kCCAttributeNamePosition index:kCCAttribPosition];
        [shaderProgram_ addAttribute:kCCAttributeNameColor index:kCCAttribColor];
        [shaderProgram_ addAttribute:kCCAttributeNameTexCoord index:kCCAttribTexCoords];

        [shaderProgram_ link];
        [shaderProgram_ updateUniforms];

        // Gets the location of the texture and mask uniforms
        _textureLocation = glGetUniformLocation( shaderProgram_->program_, "u_texture");
        _maskLocation = glGetUniformLocation( shaderProgram_->program_, "u_mask");
    }

    return self;
}

To finish override the draw method with this:

- (void)draw
{
    CC_NODE_DRAW_SETUP();

    ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex);
    ccGLBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    [shaderProgram_ setUniformForModelViewProjectionMatrix];

    glActiveTexture(GL_TEXTURE0);
    glBindTexture( GL_TEXTURE_2D, [texture_ name] );
    glUniform1i(textureLocation_, 0);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture( GL_TEXTURE_2D, [maskTexture_ name] );
    glUniform1i(maskLocation_, 1);

#define kQuadSize sizeof(quad_.bl)
    long offset = (long)&quad_;

    // vertex
    NSInteger diff = offsetof( ccV3F_C4B_T2F, vertices);
    glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));

    // texCoods
    diff = offsetof( ccV3F_C4B_T2F, texCoords);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));

    // color
    diff = offsetof( ccV3F_C4B_T2F, colors);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);    
    glActiveTexture(GL_TEXTURE0);
}

This will just apply your texture as the mask of the sprite. You don't need another step. you can add sprites as children of this one and they will be masked automatically.

There is only 3 steps to retain:

  1. Adding the shader (is already made)
  2. Initialized the shader and keep track of the mask's texture and location
  3. Override the draw method with the given method

I hope it'll help you

share|improve this answer
    
" you can add sprites as children of this one and they will be masked automatically." what do you mean? Do you mean that child sprite of a masked sprite will also be masked (?) –  Jonny Aug 22 '13 at 8:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.