【问题标题】:How to colorize a grayscale CCSprite in cocos2d?如何在 cocos2d 中为灰度 CCSprite 着色?
【发布时间】:2013-01-28 05:44:13
【问题描述】:

我想通过编程给cocos2d中的一个灰度CCSprite上色,比如灰度CCSprite是:

http://cc.cocimg.com/bbs/attachment/Fid_18/18_171059_43b48b6f1bc40a5.png

输出 CCSprite 是:

http://cc.cocimg.com/bbs/attachment/Fid_18/18_171059_574b2f34cb78b49.png

但我无法得到正确的结果。

如果我使用 [CCSprite setColor],我得到一个 CCSprite 是深色的 我使用了 CCRenderTexture 并尝试了两种不同的 blendFunc,

-(CCSprite *) try1:(CCSprite *)gray color:(ccColor3B) color
{
    CCRenderTexture *rtx = [CCRenderTexture renderTextureWithWidth:gray.contentSize.width height:gray.contentSize.height];
    ccColor4F c = ccc4FFromccc3B(color);
    [rtx beginWithClear:c.r g:c.g b:c.b a:c.a];
    gray.position = ccp(gray.contentSize.width/2, gray.contentSize.height/2);
    gray.blendFunc = (ccBlendFunc){GL_ONE_MINUS_SRC_COLOR, GL_SRC_COLOR};
    [gray visit];
    [rtx end];

    CCSprite *sp = [CCSprite spriteWithTexture:rtx.sprite.texture];
    sp.flipY = YES;
    return sp;
}

另一个是:

-(CCSprite *) try2:(CCSprite *)gray color:(ccColor3B) color
{
    CCRenderTexture *rtx = [CCRenderTexture renderTextureWithWidth:gray.contentSize.width height:gray.contentSize.height];
    ccColor4F c = ccc4FFromccc3B(color);
    [rtx beginWithClear:c.r g:c.g b:c.b a:0];
    gray.position = ccp(gray.contentSize.width/2, gray.contentSize.height/2);
    gray.blendFunc = (ccBlendFunc){GL_SRC_COLOR, GL_SRC_ALPHA};
    [gray visit];
    [rtx end];

    CCSprite *sp = [CCSprite spriteWithTexture:rtx.sprite.texture];
    sp.flipY = YES;
    return sp;
}

我什至尝试过着色器:

#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D u_texture;
varying vec2 v_texCoord;
varying vec4 v_fragmentColor;

uniform vec4 u_fillcolor;

#pragma debug(on)

void main(void)
{
    vec4 c = texture2D(u_texture, v_texCoord);

    float r;
    float g;
    float b;

    r = u_fillcolor.r + (2.0 * c.r - 1.0);
    g = u_fillcolor.g + (2.0 * c.g - 1.0);
    b = u_fillcolor.b + (2.0 * c.b - 1.0);

    gl_FragColor = vec4(r,g,b, c.a);
}

但输出不正确。

您能帮我找到输出正确 CCSprite 的方法吗?

谢谢。

(我是stackoverflow的新用户,我的声誉不足以添加图片,所以我必须添加图片作为链接。)

【问题讨论】:

    标签: cocos2d-iphone shader grayscale colorize


    【解决方案1】:

    如果您不经常更改颜色,此方法将有效。

    typedef struct _SOARGB {
        unsigned char a;
        unsigned char r;
        unsigned char g;
        unsigned char b;
    } SOARGB;
    
    +(CGImageRef)colorizeImage:(CGImageRef)image {
        CGContextRef contextRef = [self createARGBBitmapContext:image];
        NSAssert(contextRef != nil, @"Failed to create context");
        // Get image width, height. We'll use the entire image.
        size_t width = CGImageGetWidth(image);
        size_t height = CGImageGetHeight(image);
        CGRect rect = {{0,0},{width,height}};
    
        // Draw the image to the bitmap context.
        CGContextDrawImage(contextRef, rect, image);
    
        // Get a pointer to the image data associated with the bitmap context.
        SOARGB *data = (SOARGB*)CGBitmapContextGetData (contextRef);
        NSAssert(data != NULL, @"Could not retrieve pixel data from context");
    
        //
        // Do the colorization job.
        //
    
        // This colorization method is ONLY an example and
        // should probably be changed!
        SOARGB tint;
        tint.r = 255;
        tint.g = 0;
        tint.b = 0;
        tint.a = 0;
    
        for (int i = 0; i < width*height; i++) {
            SOARGB *c = &data[i];
            CGFloat alpha = c->r / 255.0;
            c->r -= (c->r - tint.r)*0.3*alpha*alpha;
            c->g -= (c->g - tint.g)*0.3*alpha*alpha;
            c->b -= (c->b - tint.b)*0.3*alpha*alpha;
        }
    
        // End of coloriation job
    
        // Create image from modified context
        return CGBitmapContextCreateImage(contextRef);
    }
    
    +(CGContextRef)createARGBBitmapContext:(CGImageRef)inImage {
        CGContextRef    context = NULL;
        CGColorSpaceRef colorSpace;
        void *          bitmapData;
        int             bitmapByteCount;
        int             bitmapBytesPerRow;
    
        // Get image width, height. We'll use the entire image.
        size_t pixelsWide = CGImageGetWidth(inImage);
        size_t pixelsHigh = CGImageGetHeight(inImage);
    
        // Declare the number of bytes per row. Each pixel in the bitmap in this
        // example is represented by 4 bytes; 8 bits each of red, green, blue, and
        // alpha.
        bitmapBytesPerRow   = (pixelsWide * 4);
        bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
    
        // Use the generic RGB color space.
        colorSpace = CGColorSpaceCreateDeviceRGB();
        if (colorSpace == NULL)
        {
            fprintf(stderr, "Error allocating color space\n");
            return NULL;
        }
    
        // Allocate memory for image data. This is the destination in memory
        // where any drawing to the bitmap context will be rendered.
        bitmapData = malloc( bitmapByteCount );
        if (bitmapData == NULL)
        {
            fprintf (stderr, "Memory not allocated!");
            CGColorSpaceRelease( colorSpace );
            return NULL;
        }
    
        // zeroing out the data
        memset(bitmapData, 0, bitmapByteCount);
    
        // Create the bitmap context. We want pre-multiplied ARGB, 8-bits
        // per component. Regardless of what the source image format is
        // (CMYK, Grayscale, and so on) it will be converted over to the format
        // specified here by CGBitmapContextCreate.
        context = CGBitmapContextCreate (bitmapData,
                                         pixelsWide,
                                         pixelsHigh,
                                         8,      // bits per component
                                         bitmapBytesPerRow,
                                         colorSpace,
                                         kCGImageAlphaPremultipliedFirst);
        if (context == NULL)
        {
            free (bitmapData);
            fprintf (stderr, "Context not created!");
        }
    
        // Make sure and release colorspace before returning
        CGColorSpaceRelease( colorSpace );
    
        return context;
    }
    

    使用上述方法加载精灵:

    UIImage *image = [UIImage imageNamed:@"myImage.png"];
    CGImageRef colorizedImageRef = [self colorizeImage:image.CGImage];
    CCSprite *colorizedSprite = [CCSprite spriteWithCGImage:colorizedImageRef key:@"myImage"];
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-23
      • 2010-12-22
      • 2023-02-22
      • 2010-11-27
      • 1970-01-01
      • 2012-05-28
      • 2017-07-31
      相关资源
      最近更新 更多