zoukankan      html  css  js  c++  java
  • cocos2dx shader实现灰度图android后台切换回来导致图像偏移的问题

      项目中经常会遇到将一张图像处理成灰色的需求,为了节省资源,一般不会让美术再做一套同样的灰度图,通常会通过代码处理让图片变灰。网上也有很多用shader处理图片变灰的方法,这些方法确实也实现了让图片变灰的需求,但是android平台从后台切换回来的时候,shader被释放,导致图片位置错乱。关键在于从android后台切换回来的时候需要重新加载shader。我们看一下cocos2dx原生的shader处理方式,我们从cocos2dx库中找到CCShaderCache.cpp,发现这个类有个reloadDefaultShaders方法,这个方法是重新加载shader,但它在ios平台没被调用,而在android平台,jni/main.cpp中被调用了,我们看一下main.cpp:

     1 void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)
     2 {
     3     if (!CCDirector::sharedDirector()->getOpenGLView())
     4     {
     5         CCEGLView *view = CCEGLView::sharedOpenGLView();
     6         view->setFrameSize(w, h);
     7 
     8         AppDelegate *pAppDelegate = new AppDelegate();
     9         CCApplication::sharedApplication()->run();
    10     }
    11    else
    12    {
    13        ccGLInvalidateStateCache();
    14        CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
    15        ccDrawInit();
    16        CCTextureCache::reloadAllTextures();
    17        CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_FOREGROUND, NULL);
    18        CCDirector::sharedDirector()->setGLDefaultValues(); 
    19    }
    20 }

    CCShaderCache::sharedShaderCache()->reloadDefaultShaders();这一行代码就是重新加载shader。好了,问题找到了,只要我们在这个地方重新init一下shader就ok了。我将网上一种可行的处理方式粘贴到下面,给大家参考:

    1、写好一个图像变灰的shader程序,并放入到cocos2dx引擎下面的shader文件夹中。

     1 //ccShader_PositionTextureGray_frag.h
     2 "                                           
    
     3 #ifdef GL_ES                                
    
     4 precision mediump float;                    
    
     5 #endif                                      
    
     6 
    
     7 uniform sampler2D u_texture;                
    
     8 varying vec2 v_texCoord;                    
    
     9 varying vec4 v_fragmentColor;               
    
    10 
    
    11 void main(void)                             
    
    12 {                                           
    
    13 // Convert to greyscale using NTSC weightings               
    
    14 vec4 col = texture2D(u_texture, v_texCoord);                
    
    15 float grey = dot(col.rgb, vec3(0.299, 0.587, 0.114));       
    
    16 gl_FragColor = vec4(grey, grey, grey, col.a);               
    
    17 }                                           
    
    18 ";

    2、ccShaders.h中添加

    1 extern CC_DLL const GLchar * ccPositionTextureGray_frag;

    3、ccShaders.cpp中添加

    1 const GLchar * ccPositionTextureGray_frag =
    2 #include "ccShader_PositionTextureGray_frag.h"

    4、CCGLProgram.h中添加

    1 #define kCCShader_PositionTextureGray               "ShaderPositionTextureGray"

    5、CCShaderCache.cpp中添加枚举类型

     1 enum {
     2     kCCShaderType_PositionTextureColor,
     3     kCCShaderType_PositionTextureColorAlphaTest,
     4     kCCShaderType_PositionColor,
     5     kCCShaderType_PositionTexture,
     6     kCCShaderType_PositionTexture_uColor,
     7     kCCShaderType_PositionTextureA8Color,
     8     kCCShaderType_Position_uColor,
     9     kCCShaderType_PositionLengthTexureColor,
    10     kCCShaderType_ControlSwitch,
    11     
    12     kCCShaderType_MAX,
    13 
    14     kCCShaderType_PositionTextureGray,
    15 };

    CCShaderCache::loadDefaultShaders()中添加

    1 // Position Texture Gray shader
    2 p = new CCGLProgram();
    3 loadDefaultShader(p, kCCShaderType_PositionTextureGray);
    4 
    5 m_pPrograms->setObject(p, kCCShader_PositionTextureGray);
    6 p->release();

    CCShaderCache::reloadDefaultShaders()中添加

    1 //
    2 // Position Texture Gray shader
    3 //
    4 p = programForKey(kCCShader_PositionTextureGray);
    5 p->reset();
    6 loadDefaultShader(p, kCCShaderType_PositionTextureGray);

    CCShaderCache::loadDefaultShader(CCGLProgram *p, int type)中添加

    1 case kCCShaderType_PositionTextureGray:
    2        p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureGray_frag);
    3  
    4         p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
    5         p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
    6         p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
    7  
    8         break;

    6、新建一个灰度转换调用类(以便扩展其他的颜色转换)

     1 //ColorUtils.h
     2 #ifndef __COLOR_UTILS_H__
     3 #define __COLOR_UTILS_H__
     4  
     5 #include "cocos2d.h"
     6 
     7 USING_NS_CC;
     8 
     9 class ColorUtils
    10 {
    11 public:
    12     ColorUtils();
    13     ~ColorUtils();
    14  
    15     static void AddColorGray(CCSprite * spr);
    16     static void RemoveColorGray(CCSprite * spr);
    17  
    18 private:
    19 };
    20 #endif
    21 
    22 //ColorUtils.cpp
    23 #include "ColorUtils.h"
    24  
    25 ColorUtils::ColorUtils()
    26 {
    27 
    28 }
    29  
    30 ColorUtils::~ColorUtils()
    31 {
    32 
    33 }
    34  
    35 void ColorUtils::AddColorGray(CCSprite * spr)
    36 {
    37     spr->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureGray));
    38 }
    39  
    40 void ColorUtils::RemoveColorGray(CCSprite * spr)
    41 {
    42     spr->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
    43 }

    原文链接 http://my.oschina.net/u/1430085/blog/191673

    (在不断的尝试中总结经验,以帮助后面的人更快的上路)

  • 相关阅读:
    Java 联系Oracle 数据库
    android 流量统计
    [Angular] Using the Argon 2 Hashing Function In Our Sign Up Backend Service
    [Angular] Use Angular’s @HostBinding and :host(...) to add styling to the component itself
    [Angular] Use Angular style sanitization to mark dynamic styles as trusted values
    [D3] Build a Line Chart with D3 v4
    [Angular] Style HTML elements in Angular using ngStyle
    [Firebase] Firebase Cloud Functions
    [React] Theme your application with styled-components and "ThemeProvider"
    [Angular] Component architecture and Reactive Forms
  • 原文地址:https://www.cnblogs.com/yeshanghai/p/cocos2dx_shader.html
Copyright © 2011-2022 走看看