转自:http://www.tuicool.com/articles/U3URRrI

项目中经常会遇到将一张图像处理成灰色的需求,为了节省资源,一般不会让美术再做一套同样的灰度图,通常会通过代码处理让图片变灰。网上也有很多用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();
        view->setFrameSize(w, h);
  6.     AppDelegate *pAppDelegate = new AppDelegate();
  7.     CCApplication::sharedApplication()->run();
  8.   }else{
  9.     ccGLInvalidateStateCache();
  10.     CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
  11.     ccDrawInit();
  12.     CCTextureCache::reloadAllTextures();
  13.     CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_FOREGROUND, NULL);
  14.     CCDirector::sharedDirector()->setGLDefaultValues();
  15.   }
  16. }
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
这一行代码就是重新加载shader。好了,问题找到了,只要我们在这个地方重新init一下shader就ok了。我将网上一种可行的处理方式粘贴到下面,给大家参考:
 
1、写好一个图像变灰的shader程序,并放入到cocos2dx引擎下面的shader文件夹中。
  1. //ccShader_PositionTextureGray_frag.h
  2. " \n\
  3. #ifdef GL_ES \n\
  4. precision mediump float; \n\
  5. #endif \n\
  6. \n\
  7. uniform sampler2D u_texture; \n\
  8. varying vec2 v_texCoord; \n\
  9. varying vec4 v_fragmentColor; \n\
  10. \n\
  11. void main(void) \n\
  12. { \n\
  13. // Convert to greyscale using NTSC weightings \n\
  14. vec4 col = texture2D(u_texture, v_texCoord); \n\
  15. float grey = dot(col.rgb, vec3(0.299, 0.587, 0.114)); \n\
  16. gl_FragColor = vec4(grey, grey, grey, col.a); \n\
  17. } \n\
  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. }

cocos2dx shader实现灰度图android后台切换回来导致图像偏移的问题的更多相关文章

  1. S0.2 灰度图

    目录 灰度图定义 灰度图优点 RGB转灰度算法(OpenCV3) 量化 算法公式 OpenCV自带函数实现 综合比较 灰度图定义 对于单色(灰度)图像而言,每个像素的亮度用一个数值来表示,通常数值范围 ...

  2. [FMX]将 Android 程序切换到后台及从后台切换到前台实现

    有时候,我们需要将自己的Android程序切换到后台运行,在必要时,将其切换到前台运行.下面提供了一种实现方式,首先需要引用三个单元:   1 uses Androidapi.JNI.App,Andr ...

  3. Android 将ARGB图片转换为灰度图

    思路如下: 1.读取or照相,得到一张ARGB图片. 2.转化为bitmap类,并对其数据做如下操作: A通道保持不变,然后逐像素计算:X = 0.3×R+0.59×G+0.11×B,并使这个像素的值 ...

  4. cocos2dx - shader实现任意动画的残影效果

    本节主要讲利用cocos2dx机制实现opengl es shader脚本的绘制 这里先看下最终效果:                      这里分别实现了灰度效果及残影的效果. 一.绘制基类 这 ...

  5. Android-将RGB彩色图转换为灰度图

    package com.example.yanlei.wifi; import android.graphics.Bitmap; import android.graphics.BitmapFacto ...

  6. android 语言切换过程分析

    android 语言切换过程分析 2014-02-27 18:13 1207人阅读 评论(0) 收藏 举报 语言切换android语言切换android改变语言 最近在看一个bug,系统切换语言后,本 ...

  7. 2.x最终照着教程,成功使用OpenGL ES 绘制纹理贴图,添加了灰度图

    在之前成功绘制变色的几何图形之后,今天利用Openg ES的可编程管线绘制出第一张纹理. 学校时候不知道OpenGL的重要性,怕晦涩的语法.没有跟老师学习OpenGL的环境配置,现在仅仅能利用coco ...

  8. Learning Cocos2d-x for WP8(6)——场景切换和场景过渡效果

    原文:Learning Cocos2d-x for WP8(6)--场景切换和场景过渡效果 C#(wp7)兄弟篇 Learning Cocos2d-x for XNA(6)——场景切换和场景过渡效果 ...

  9. 全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)

    本文原作者“minminaya”,作者网站:minminaya.cn,为了提升文章品质,即时通讯网对内容作了幅修订和改动,感谢原作者. 1.引言 对于IM应用和消息推送服务的开发者来说,在Androi ...

随机推荐

  1. linux 开机自动启动脚本方法

    通过现场对这次天津iptv demo项目的调测.对iptv这套系统有了更好的认识和理解.由于iptv本身需要安装许多服务.而现场实施中有没有把这些需要启动服务的脚本加入到开 机自动运行中.如果服务器重 ...

  2. oracle 常用语句

    创建用户及授权create temporary tablespace test_temp tempfile 'C:\oracle\product\10.2.0\oradata\hszxdbtemp.d ...

  3. hibernate建表一对多 一的一方控制多的方

    级联操作,操作class对象的时候 级联操作 student Classes.java文件 package cn.itcast.hiberate.sh.domain; import java.util ...

  4. [搜片神器]直接从DHT网络下载BT种子的方法

    DHT抓取程序开源地址:https://github.com/h31h31/H31DHTDEMO 数据处理程序开源地址:https://github.com/h31h31/H31DHTMgr DHT系 ...

  5. 线程局部变量ThreadLocal的原理及使用范围_1

    线程局部变量ThreadLocal的原理及使用范围 使用原理 每个Thread中都有一个ThreadLocalMap成员, 该成员是ThreadLocal的内部类ThreadLocalMap类型.每使 ...

  6. B-Tree、B+Tree和B*Tree

    B-Tree(这儿可不是减号,就是常规意义的BTree) 是一种多路搜索树: 1.定义任意非叶子结点最多只有M个儿子:且M>2: 2.根结点的儿子数为[2, M]: 3.除根结点以外的非叶子结点 ...

  7. 使用最小堆来完成k路归并 6.5-8

    感谢:http://blog.csdn.net/mishifangxiangdefeng/article/details/7668486 声明:供自己学习之便而收集整理 题目:请给出一个时间为O(nl ...

  8. 用js完成blog项目

    //前台调用 var $ = function (args) { return new Base(args); } //基础库 function Base(args) { //创建一个数组,来保存获取 ...

  9. (转)Java关键字final、static使用总结

    一.final  根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量.你可能出于两种理解而需要阻止改变:设计或效率. fin ...

  10. PV3D学习笔记-导入DAE模型

      网上关于PV3D导入DAE模型的例子都非常多,可惜我研究了半天,一个都没成功,或者是破面问题,或者是贴图不显示,再或者贴图乱掉了.今天晚上终于搞定,心得发上来. 制作模型的软件是SketchUp ...