[zz]cc灰白圖生成

遊戲中人物死掉後要把人物頭像變成灰白圖,不少遊戲也是這樣處理,問題來了,怎麼將CCsprite生成的圖變成灰白呢?web

 

看了下實現,基本有了辦法。CCSprite是在initWithTexture的時候渲染的貼圖,若是在這裏面設置一個一個灰度Shader,也許能夠將圖片改爲灰白色。ide

 

GL Shader腳本代碼:函數



[cpp]   view plain copy
  1. #ifdef GL_ES  
  2. precision mediump float;  
  3. #endif  
  4. uniform sampler2D u_texture;  
  5. varying vec2 v_texCoord;  
  6. varying vec4 v_fragmentColor;  
  7. void main(void)  
  8. {  
  9. // Convert to greyscale using NTSC weightings  
  10. float alpha = texture2D(u_texture, v_texCoord).a;  
  11. float grey = dot(texture2D(u_texture, v_texCoord).rgb, vec3(0.299, 0.587, 0.114));  
  12. gl_FragColor = vec4(grey, grey, grey, alpha);  
  13. }  




這個主要目的是將RGB值轉換爲YUV值,Y就是灰度,因此咱們取出裏面的Y值來實現咱們的灰白圖。ui

 

Google了下,vec3(0.299, 0.587, 0.114) 是RGB轉YUV的參數值。this

 

計算完了以後根據原來的紋理alpha值,輸出咱們處理後的顏色到gl_FragColor,就能夠讓shader去渲染黑白圖。url

 

裏面主要是在光柵化後的片斷進行顏色處理,最後輸出的是像素,它不會產生額外紋理,因此不會卡。spa

 

注意:GLSL1.0的可能有些函數不支持,會crash。不過目前基本能夠不考慮。.net

 

下面就是我寫好的類,加入本身的工程就能夠了。orm

 

頭文件blog

 

[cpp]   view plain copy
  1. //  
  2. // BYGraySprite.h  
  3. // Demo  
  4. //  
  5. // Created by Yanghui Liu on 12-11-2.  
  6. // Copyright (c) 2012年 BoyoJoy. All rights reserved.  
  7. //  
  8.   
  9.   
  10. #ifndef Demo_BYGraySprite_h  
  11. #define Demo_BYGraySprite_h  
  12.   
  13.   
  14. #include "cocoa/CCGeometry.h"  
  15. #include "cocos2d.h"  
  16. USING_NS_CC;  
  17.   
  18.   
  19. class BYGraySprite : public CCSprite{  
  20.   
  21.   
  22. public:  
  23.  BYGraySprite();  
  24.  virtual ~BYGraySprite();  
  25.  static BYGraySprite* create(const char* pszFileName);  
  26.  bool initWithTexture(CCTexture2D* pTexture, const CCRect& tRect);  
  27.  virtual void draw();  
  28.   
  29.   
  30. };  
  31.   
  32.   
  33. #endif  



cpp文件


[cpp]   view plain copy
  1. //  
  2. // BYGraySprite.cpp  
  3. // Demo  
  4. //  
  5. // Created by Yanghui Liu on 12-11-2.  
  6. // Copyright (c) 2012年 BoyoJoy. All rights reserved.  
  7. //  
  8.   
  9.   
  10. #include "BYGraySprite.h"  
  11.   
  12.   
  13. BYGraySprite::BYGraySprite(){  
  14.   
  15.   
  16. }  
  17.   
  18.   
  19. BYGraySprite::~BYGraySprite(){  
  20.   
  21.   
  22. }  
  23.   
  24.   
  25. BYGraySprite* BYGraySprite::create( const char* pszFileName ){  
  26.  BYGraySprite* graySprite = new BYGraySprite;  
  27.  if (graySprite && graySprite->initWithFile(pszFileName)){  
  28.  graySprite->autorelease();  
  29.  return graySprite;  
  30.  }else{  
  31.  CC_SAFE_RELEASE(graySprite);  
  32.  return NULL;  
  33.  }  
  34. }  
  35.   
  36.   
  37. bool BYGraySprite::initWithTexture(CCTexture2D* pTexture, const CCRect& tRect ){  
  38.  do{  
  39.  CC_BREAK_IF(!CCSprite::initWithTexture(pTexture, tRect));  
  40.   
  41.   
  42.  GLchar* pszFragSource =  
  43.  "#ifdef GL_ES \n \  
  44.  precision mediump float; \n \  
  45.  #endif \n \  
  46.  uniform sampler2D u_texture; \n \  
  47.  varying vec2 v_texCoord; \n \  
  48.  varying vec4 v_fragmentColor; \n \  
  49.  void main(void) \n \  
  50.  { \n \  
  51.  // Convert to greyscale using NTSC weightings \n \  
  52.  float grey = dot(texture2D(u_texture, v_texCoord).rgb, vec3(0.299, 0.587, 0.114)); \n \  
  53.  gl_FragColor = vec4(grey, grey, grey, 1.0); \n \  
  54.  }";  
  55.   
  56.   
  57.  CCGLProgram* pProgram = new CCGLProgram();  
  58.  pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, pszFragSource);  
  59.  this->setShaderProgram(pProgram);  
  60.  pProgram->release();  
  61.  CHECK_GL_ERROR_DEBUG();  
  62.   
  63.   
  64.  this->getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);  
  65.  this->getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);  
  66.  this->getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);  
  67.  CHECK_GL_ERROR_DEBUG();  
  68.   
  69.   
  70.  this->getShaderProgram()->link();  
  71.  CHECK_GL_ERROR_DEBUG();  
  72.   
  73.   
  74.  this->getShaderProgram()->updateUniforms();  
  75.  CHECK_GL_ERROR_DEBUG();  
  76.   
  77.   
  78.  return true;  
  79.  } while (0);  
  80.  return false;  
  81. }  
  82.   
  83.   
  84. void BYGraySprite::draw(){  
  85.  ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex );  
  86.  ccGLBlendFunc( m_sBlendFunc.src, m_sBlendFunc.dst );  
  87.   
  88.   
  89.  this->getShaderProgram()->use();  
  90.  this->getShaderProgram()->setUniformForModelViewProjectionMatrix();  
  91.   
  92.   
  93.  ccGLBindTexture2D( this->getTexture()->getName() );  
  94.   
  95.   
  96. #define kQuadSize sizeof(m_sQuad.bl)  
  97.  long offset = (long)&m_sQuad;  
  98.   
  99.   
  100.  // vertex  
  101.  int diff = offsetof( ccV3F_C4B_T2F, vertices);  
  102.  glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff));  
  103.   
  104.   
  105.  // texCoods  
  106.  diff = offsetof( ccV3F_C4B_T2F, texCoords);  
  107.  glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));  
  108.   
  109.   
  110.  // color  
  111.  diff = offsetof( ccV3F_C4B_T2F, colors);  
  112.  glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff));  
  113.  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);  
  114.  CC_INCREMENT_GL_DRAWS(1);  
  115. }  





使用方法:

[cpp]   view plain copy
  1. BYGraySprite* graySprite = BYGraySprite::create("Icon.png");  
  2.  graySprite->setPosition( ccp(size.width/2, size.height/2) );  
  3.  this->addChild(graySprite);  

2、以前alpha值是直接用的1,因此透明圖會渲染成黑色。把原來紋理的alpha取出來並使用。就能夠避免該問題。

也就是將GL腳本代碼中的

float grey = dot(texture2D(u_texture, v_texCoord).rgb, vec3(0.299, 0.587, 0.114)); \n \

gl_FragColor = vec4(grey, grey, grey, 1.0); \n \

改爲:

vec4 col = texture2D(u_texture, v_texCoord); \n \

float grey = dot(col.rgb, vec3(0.299, 0.587, 0.114)); \n \

gl_FragColor = vec4(grey, grey, grey, col.a); \n \