转自: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:

void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)
{
  if (!CCDirector::sharedDirector()->getOpenGLView())
  {
    CCEGLView *view = CCEGLView::sharedOpenGLView();
    view->setFrameSize(w, h);
    AppDelegate *pAppDelegate = new AppDelegate();
    CCApplication::sharedApplication()->run();
  }else{
    ccGLInvalidateStateCache();
    CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
    ccDrawInit();
    CCTextureCache::reloadAllTextures();
    CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_FOREGROUND, NULL);
    CCDirector::sharedDirector()->setGLDefaultValues();
  }
}
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
这一行代码就是重新加载shader。好了,问题找到了,只要我们在这个地方重新init一下shader就ok了。我将网上一种可行的处理方式粘贴到下面,给大家参考:
 
1、写好一个图像变灰的shader程序,并放入到cocos2dx引擎下面的shader文件夹中。
//ccShader_PositionTextureGray_frag.h
" \n\
#ifdef GL_ES \n\
precision mediump float; \n\
#endif \n\
\n\
uniform sampler2D u_texture; \n\
varying vec2 v_texCoord; \n\
varying vec4 v_fragmentColor; \n\
\n\
void main(void) \n\
{ \n\
// Convert to greyscale using NTSC weightings \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\
} \n\
";

2、     ccShaders.h中添加

extern CC_DLL const GLchar * ccPositionTextureGray_frag;

3、ccShaders.cpp中添加

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

4、CCGLProgram.h中添加

#define kCCShader_PositionTextureGray  "ShaderPositionTextureGray"

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

enum {
kCCShaderType_PositionTextureColor,
kCCShaderType_PositionTextureColorAlphaTest,
kCCShaderType_PositionColor,
kCCShaderType_PositionTexture,
kCCShaderType_PositionTexture_uColor,
kCCShaderType_PositionTextureA8Color,
kCCShaderType_Position_uColor,
kCCShaderType_PositionLengthTexureColor,
kCCShaderType_ControlSwitch, kCCShaderType_MAX, kCCShaderType_PositionTextureGray,
};

CCShaderCache::loadDefaultShaders()中添加

// Position Texture Gray shader
p = new CCGLProgram();
loadDefaultShader(p, kCCShaderType_PositionTextureGray); m_pPrograms->setObject(p, kCCShader_PositionTextureGray);
p->release();

CCShaderCache::reloadDefaultShaders()中添加

//
// Position Texture Gray shader
//
p = programForKey(kCCShader_PositionTextureGray);
p->reset();
loadDefaultShader(p, kCCShaderType_PositionTextureGray);

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

case kCCShaderType_PositionTextureGray:
  p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureGray_frag); p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); break;

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

//ColorUtils.h
#ifndef __COLOR_UTILS_H__
#define __COLOR_UTILS_H__ #include "cocos2d.h" USING_NS_CC; class ColorUtils
{
public:
ColorUtils();
~ColorUtils(); static void AddColorGray(CCSprite * spr);
static void RemoveColorGray(CCSprite * spr); private:
};
#endif //ColorUtils.cpp
#include "ColorUtils.h" ColorUtils::ColorUtils()
{ } ColorUtils::~ColorUtils()
{ } void ColorUtils::AddColorGray(CCSprite * spr)
{
spr->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureGray));
} void ColorUtils::RemoveColorGray(CCSprite * spr)
{
spr->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
}

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. 利用命令控制台cmd进入某个硬盘的某个文件夹的命令是什么?

    在命令行窗口中输入F:后回车就可以切换到F盘,如果想查看F盘的内容,可以再输入dir后回车 (输入“F”后要再输入一个“ :”再回车才行哦)

  2. tengine+lua的安装步骤

    我是在Red Hat 5.8 的虚机上安装的. Nginx的一些模块需要其他第三方库的支持,例如gzip模块需要zlib库,rewrite模块需要pcre库,ssl功能需要openssl库等.建议把这 ...

  3. 【转】Linux下创建、销毁、使用 SWAP

    转自:http://blog.csdn.net/wxqee/article/details/7970110 创建swap文件方法 1) 创建一个足够大的文件 dd if=/dev/zero of=/l ...

  4. 关于Cygwin的x-Server的自动运行以及相关脚本修改

    常常需要用到远端服务器的图形工具,如果在windows端没用xserver的话,很多程序无法运行.一个特殊的例子,emacs在没用xserver的时候,是直接在终端中打开的,如果不修改cygwin.b ...

  5. 部署WAR文件到tomcat

    1.启动tomcat服务 2.在浏览器的地址栏输入地址“http://localhost:8080/manager/html”进入tomcat管理界面. 如果要管理的服务器是在网络中,则将localh ...

  6. 【LeetCode】28 - Implement strStr()

    Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle ...

  7. C++中的基类与派生类

    派生类的继承方式总结: 继承方式 说明 public 基类的public和protected的成员被派生类继承后,保持原来的状态 private 基类的public和protected的成员被派生类继 ...

  8. C++二叉树的实现

    C++实现二叉查找树 啥是二叉查找树 在数据结构中,有一个奇葩的东西,说它奇葩,那是因为它重要,这就是树.而在树中,二叉树又是当中的贵族.二叉树的一个重要应用是它们在查找中的应用,于是就有了二叉查找树 ...

  9. IOS平台设计规范

    一.UI的控件概述: 1.框架UI的元素分为4类: A:栏:状态栏目和导航栏的结合体; B:内容视图:应用显示的内容信息,包括相关的交互行为,例如滚屏.插入.删除等操作进行排序; C:控制元素:产品行 ...

  10. 使用iphone5修剪视频的方法

    iphone5有很高的视频拍摄质量,这人很多业余爱好者也加入了视频短片的拍摄当中.在拍摄视频的过程中,为了能够捕捉到精彩瞬间,常常会提前拍摄,并延迟结束拍摄,这样就给视频增加了很多无意义的片段.这时, ...