在cocos2d中添加自己的shader教程

mark下:转载:http://www.cocoachina.com/bbs/read.php?tid=220630

1.cocos2d的shader都是共用的, 存放在   GLProgramCache 中。 当setGLProgram() 的时候是从GLProgramStateCache 中寻找是否有这个shader的State, 有就返回,这个也是共用的,任意一个GLProgramState修改了, 都会影响到使用这个shader的对象

添加shader的方法:

先编写shader: (直接复制cocos/renderer/ 下的 **.frag或者**.vert )  frag是PS阶段的shader  .vert是VS,然后按照自己的修改。
注意 这些shader在加载的时候,cocos2d会自动添加几个必须的属性变量:

const GLchar *sources[] = {
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_LINUX && CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
        (type == GL_VERTEX_SHADER ? "precision highp float;\n" : "precision mediump float;\n"),
#endif
        "uniform mat4 CC_PMatrix;\n"
        "uniform mat4 CC_MVMatrix;\n"
        "uniform mat4 CC_MVPMatrix;\n"
        "uniform vec4 CC_Time;\n"
        "uniform vec4 CC_SinTime;\n"
        "uniform vec4 CC_CosTime;\n"
        "uniform vec4 CC_Random01;\n"
        "uniform sampler2D CC_Texture0;\n"
        "uniform sampler2D CC_Texture1;\n"
        "uniform sampler2D CC_Texture2;\n"
        "uniform sampler2D CC_Texture3;\n"
        "//CC INCLUDES END\n\n",
        source,
    };

这段代码在: bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source) 中,所以你在编写自己的shader时候要注意不要和上面的变量重名
编写方式:
现在ccShaders.h中添加shader的编码保存的变量:(拿做的灰度效果为列:)
extern CC_DLL const GLchar * ccPositionTextureColor_noMVP_gray_frag;

我直接修改 ccShader_PositionTextureColor_noMVP.frag 这个文件的
源文件:

const char* ccPositionTextureColor_noMVP_frag = STRINGIFY(
\n#ifdef GL_ES\n
precision lowp float;
\n#endif\n

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

uniform int n_isGray;

void main()
{
 if (n_isGray == 1)
 {
  float alpha = texture2D(CC_Texture0, v_texCoord).a;
  float grey = dot(texture2D(CC_Texture0, v_texCoord).rgb, vec3(0.299, 0.587, 0.114));
  gl_FragColor = vec4(1, grey, grey, 0.0);
 }
 else
 {
  gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
 }

}
);

修改后:
const char* ccPositionTextureColor_noMVP_gray_frag = STRINGIFY(
\n#ifdef GL_ES\n
precision lowp float;
\n#endif\n

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

void main()
{
 float alpha = texture2D(CC_Texture0, v_texCoord).a;
 float grey = dot(texture2D(CC_Texture0, v_texCoord).rgb, vec3(0.299, 0.587, 0.114));
 gl_FragColor = vec4(grey, grey, grey, alpha);
}
);

红色部分是修改掉的 注意 const char* ccPositionTextureColor_noMVP_gray_frag = STRINGIFY( 红色部分要和你在ccShaders.h中声明的变量一致!
然后在ccShaders.cpp中引用 编写好的shader文件 : #include "ccShader_PositionTextureColor_noMVP_gray.frag"

这样编写部分就结束

现在开始添加到默认shader里面:
先到 CCGLProgram.h   GLProgram 中添加添加我们这个shader的名字:(这个名字只是对外使用的键值)
static const char* SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY;  
在.cpp中加上: 
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY = "ShaderPositionTextureColor_noMVP_gray";

然后到CCGLProgramCache.cpp 中的 最上面有一堆枚举, 添加一个自己shader的枚举 比如我添加的 kShaderType_PositionTextureColor_noMVP_gray,

然后在 void GLProgramCache::loadDefaultGLPrograms() 中写加载我们shader的代码:
 p = new GLProgram();
 loadDefaultGLProgram(p, kShaderType_PositionTextureColor_noMVP_gray);
 _programs.insert( std::make_pair( GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY, p ) );

到void GLProgramCache::loadDefaultGLProgram(GLProgram *p, int type) 中,配置我们shader用的VS 和PS阶段的 的相关代码:(因为做灰度只需要改动pos部分,所以可以直接用cocos2d现有的VS阶段的代码ccPositionTextureColor_noMVP_vert)

case kShaderType_PositionTextureColor_noMVP_gray:
   p->initWithByteArrays(ccPositionTextureColor_noMVP_vert, ccPositionTextureColor_noMVP_gray_frag);
   break;

这样shader就添加好了, 使用方法:

GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY);
  sprite->setGLProgram(program);

还原的话就
GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP);
sprite->setGLProgram(program);

你可以脱离这套共用GLProgramState的方式 直接用: (这样你就可以控制这个shader某一个值,而不影响其他使用这个shader的对象了)
GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY); 
GLProgramState* state = GLProgramState::create(program);
sprite->setGLProgramState(state):

本人没学过opengel今天ui那边需要灰度,才开始看的, 写得不好,大家就将就看吧~
还要说一个地方

std::string GLProgram::logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc) const
{
    std::string ret;
    GLint logLength = 0, charsWritten = 0;

//infoFunc(object, GL_INFO_LOG_LENGTH, &logLength);        //编译错误的话,到这里就崩溃了~~  不知道为什么, 
 glGetShaderiv(object, GL_INFO_LOG_LENGTH, &logLength);     //我直接改成调用opengel函数, 
    if (logLength < 1)
        return "";

char *logBytes = (char*)malloc(logLength);
   // logFunc(object, logLength, &charsWritten, logBytes);
 glGetShaderInfoLog(object, logLength, &charsWritten, logBytes);
    ret = logBytes;

free(logBytes);
    return ret;
}

这里是我这篇笔记的地址: http://note.youdao.com/share/?id=f72378178898d34affe13a6dddd75df3&type=note

时间: 2024-08-06 21:50:12

在cocos2d中添加自己的shader教程的相关文章

ASP.NET MVC4 新手入门教程之八 ---8.向模式中添加验证

在这本部分会将验证逻辑添加到Movie模式,和你会确保验证规则执行任何时候用户试图创建或编辑使用该应用程序的一部电影. 保持事物的干练性 ASP.NET MVC 的核心设计信条之一是 DRY(”Don't Repeat Yourself“,不要重复).ASP.NET MVC 鼓励你只有一次,指定的功能或行为,然后让它无处不在应用程序中反映.这减少了需要编写的代码量,并使你写更少错误倾向和易于维护的代码. ASP.NET MVC 和 Entity Framework Code First 中提供的

ASP.NET 5系列教程 (四):向视图中添加服务和发布应用到公有云

向视图中添加服务 现在,ASP.NET MVC 6 支持注入类到视图中,和VC类不同的是,对类是公开的.非嵌套或非抽象并没有限制.在这个例子中,我们创建了一个简单的类,用于统计代办事件.已完成事件和平均优先级的服务. 1. 添加命名为Services 的文件夹,在该文件夹下添加名称为 StatisticsService.cs 的类: StatisticsService 类代码设计如下: using System.Linq; using System.Threading.Tasks; using

Cocos2D中Action的进阶使用技巧(一)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 假设认为写的不好请多提意见,假设认为不错请多多支持点赞.谢谢! hopy ;) 大家对Cocos2d中动作的使用大概都非常清楚了,事实上本身action的概念也不复杂. 可是在某些情况下,一般的动作不能满足我们需求的时候,我们就必须使用更高级的Action方法来解决这个问题. 比方,串行化(不是序列化哦,这是两个全然不同的概念)不同Action的执行-有些童鞋可能会说非常easy,直接用CCActionSequence不就结了,可是等等我

转载:如何在wordpress主题中添加设置页面

将自己设计的题发布或是销售是一件很棒的事情,但并不是每一个主题使用者都有很熟练的HTML/CSS技巧.但是如果在主题中整合一个设置选项页面,就可以使那些完全不懂代码的用户能够很容易地根据他们的喜好来修改主题.下面我将告诉大家如何从零开始做一个最简单的主题选项页(下图为最终效果). 我们的最终目的是什么? 在开始之前,要先了解我们的最终目的是什么?我们主题可以自行定制哪些内容?这些是需要你在设计主题前就应该考虑好的. 每个主题都可以有很多的可编辑元素,本例中我将通过实现下面这三个方面的定制来说明如

step4---&gt;往工程中添加Spring框架----&gt;修改maven的配置文件pom.xml,向工程中添加spring框架的某些模块

1.本文内容: 本文介绍使用maven向自己的项目中添加各种框架的方法,即如何配置maven的pom.xml来让maven帮助管理这些框架(包括Spring.SpringMVC.hibernate框架等等). 2.使用maven向自己的工程中添加框架: 2.1概述 若想使用maven向自己的工程中添加三方框架(如Spring.SpringMVC等),需要先确保你的工程是maven工程,如果你还不知道该如何在myeclipse中建立一个maven web project,请参考相关教程. 2.2使

[译]如何在Unity编辑器中添加你自己的工具

在这篇教程中你会学习如何扩展你的Unity3D编辑器,以便在你的项目中更好的使用它.你将会学习如何绘制你自己的gizmo,用代码来实现创建和删除物体,创建编辑器窗口,使用组件,并且允许用户撤销他们所作出的任何动作,这些全部都是用编辑器脚本来实现的. 这篇教程假设你已经熟悉Unity的基本工作流程.如果你知道如何在编辑器中创建物体.预设.场景并且知道如何移动它们,知道如何添加组件,那么你可以开始本教程的学习了. 最终结果预览 让我们看一下我们做出的最终结果是什么样子: 如你所见,我们会创建一个编辑

cocos2d-x3.2中添加Android手机震动

本人宣布从此博文发出后,我的cocos2dx的引擎从cocos2dx3.1.1跳到cocos2dx3.2,哈哈,其实变化不大的,不碍事~~~ 下面来说说在cocos中添加Android手机震动的功能,亲身体验,网上的教程都是渣渣啊,坑比的很,还要看了原帖http://www.cocos2d-x.org/boards/6/topics/8179,全英文的,蛋疼恼火了许久,才解决~~ 下面进入正题.相信看完本文,什么问题都ok了!!!! 1.在proj.android这个目录下 AndroidMan

Lua中添加触摸事件

1首先,lua中的触摸事件与cocos2d中的触摸事件相似,都需要添加监听者,都需要将监听者添加到触摸事件分发器中去 local listener=cc.EventListenerTouchOneByOne:create() listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN ) listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_T

wordpress——在插件后台管理页面中添加javascript和ajax

最近在开发一个wordpress插件,需要在插件的后台管理页面上,添加自己写的javascript文件,以达到一些功能. 查了好几天的文档和资料,终于实现了. 这里先介绍下wordpress后台页面添加javascript的过程,再介绍添加ajax的过程. 添加javascript 首先我们需要知道wordpress插件开发的框架,然后再介绍javascript添加的步骤. 添加插件设置页面 开发插件,总需要在管理后台添加自己的插件设置页面.插件设置子页面,在这些页面中,可以设置和保存插件的一些