我想通过编程为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的新用户,我的声誉不足以添加图片,因此我必须将图片添加为链接。)
答案 0 :(得分:0)
如果您不经常更改颜色,此方法将起作用。
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"];
希望这有帮助。