首页 > 代码库 > shader实现灰度图

shader实现灰度图

1cocos主线程以及Auto-batching

AppDelegate app;//封装用于智能分化,完成初始化,载入资源、构造场景、生成精灵

Application::getInstance()->run();//启动主线程

 

 director->mainLoop();//分为场景渲染,和清理缓存池

 glview->pollEvents();

 

drawScene

1)优先处理输入事件(空实现,留接口)

2)默认定时器(负优先级,0,正优先级)。自定义计时器

3visit主渲染树(autobatcch)是使用group

4visit通知窗口

5)渲染,切换缓存区

 

 

visit:中序遍历二叉树,添加RenderCommand

 

遍历结束后执行Render():

排序RenderCommand为三组:负、0、正;

RenderCommand中为QUAD_COMMAND的将会进行autoBatch处理:

_batchedQuadCommands缓存池不断添加单个QuadCommand

当前的绘制命令绘制quad单元数加上现存的绘制单元数超过缓存池容量,则执行现存的绘制操作,并清理缓存池,之后添加命令至缓冲池中。

其余绘制类型如custombatchNode则是直接执行,不执行autoBatch

GroupCommand类型是又是一组绘制队列,将递归地执行上诉过程。



1、shader绘制灰度纹理

helloworld中增加变量:

cocos2d::CustomCommand m_customCommand;

void onDraw(const cocos2d::Mat4 &transform, uint32_t flags);

cocos2d::Sprite* m_pSprite;

cocos2d::V3F_C4B_T2F_Quad m_sQuad;

 

//cpp中代码

#include "HelloWorldScene.h"

USING_NS_CC;

static Texture2D * texture2d;

 

//--------------------------------------------------------

static const GLchar* s_szColorSpriteVSH = 

" \n\

attribute vec4 a_position; \n\

attribute vec2 a_texCoord; \n\

attribute vec4 a_color; \n\

\n\

#ifdef GL_ES \n\

varying lowp vec4 v_fragmentColor; \n\

varying mediump vec2 v_texCoord; \n\

#else \n\

varying vec4 v_fragmentColor; \n\

varying vec2 v_texCoord; \n\

#endif \n\

\n\

void main() \n\

{ \n\

gl_Position = CC_MVPMatrix * a_position; \n\

v_fragmentColor = a_color; \n\

v_texCoord = a_texCoord; \n\

}";

//--------------------------------------------------------

static const GLchar* s_szColorSpriteFSH = 

" \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\

// vec3( 0.299, 0.587, 0.114 ) RGBYUV的参数值,生成灰色图 \n\

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

// 使用灰色图进行颜色混合 \n\

vec4 blendColor = vec4( 1.0, 1.0, 1.0, 1.0 ); // 调整这个值以修改最终混合色值 \n\

gl_FragColor = vec4(MixColor * blendColor.r, MixColor * blendColor.g, MixColor * blendColor.b, blendColor.a); \n\

}";

 

Scene* HelloWorld::createScene()

{

    // ‘scene‘ is an autorelease object

    auto scene = Scene::create();

    

    // ‘layer‘ is an autorelease object

    auto layer = HelloWorld::create();

 

    // add layer as a child to scene

    scene->addChild(layer);

 

    // return the scene

    return scene;

}

 

// on "init" you need to initialize your instance

bool HelloWorld::init()

{

    //////////////////////////////

    // 1. super init first

    if ( !Layer::init() )

    {

        return false;

    }

    

    Size visibleSize = Director::getInstance()->getVisibleSize();

    Vec2 origin = Director::getInstance()->getVisibleOrigin();

 

 

 

 texture2d = TextureCache::sharedTextureCache()->addImage("HelloWorld.png");

    

texture2d->getGLProgram()->initWithVertexShaderByteArray( s_szColorSpriteVSH, s_szColorSpriteFSH );  

 

 

texture2d->getGLProgram()->link();  

CHECK_GL_ERROR_DEBUG();  

 

texture2d->getGLProgram()->updateUniforms();  

CHECK_GL_ERROR_DEBUG();  

 

 

    return true;

}

 

void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)

{

m_customCommand.init(_globalZOrder);  

    m_customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw, this, transform, flags);  

    renderer->addCommand(&m_customCommand);

}

 

void HelloWorld::onDraw(const Mat4 &transform, uint32_t flags)

{

//ccGLBlendFunc( m_sBlendFunc.src, m_sBlendFunc.dst );  

static GLfloat vertext[] = {

0.0f,0.0f,0.0f,

480.0f,0.0f,0.0f,

0.0f,320.0f,0.0f,

480.0f,320.0f,0.0f

};

 

//但是纹理的读取也是逆时针,只是EG是用三角形作为基础图形去绘制其他图形,方向先绘制下三角,再绘制上三角!!!之前这里搞错了。希望大家别被我误导了

static GLfloat coord[] = {

0.0f,1.0f,

1.0f,1.0f,

0.0f,0.0f,

1.0f,0.0f

};

 

static GLfloat colors[] = {

1.0f,1.0f,1.0f,1.0f,

1.0f,1.0f,1.0f,1.0f,

1.0f,1.0f,1.0f,1.0f,

1.0f,1.0f,1.0f,1.0f,

};

 

//初始化纹理,即将纹理映射至openGL ES的世界坐标系中

coord[2] = coord[6] = texture2d->getMaxS();

coord[1] = coord[3] = texture2d->getMaxT();

 

//开启着色器,坐标、颜色、纹理

GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);

        //设置着色器

texture2d->getGLProgram()->use();

//设置统一属性,即M模型、V视图、P投影,完成从Opengl的世界坐标到屏幕坐标的映射

texture2d->getGLProgram()->setUniformsForBuiltins();

 

 

//绑定纹理,texture2d->getName() 纹理在内存或显存中存储的下标(应该是下标,我没看纹理加载,还不了解GPUCPU的通信)

glBindTexture(GL_TEXTURE_2D,texture2d->getName());

 

//设置顶点,每个顶点向量维数为3,数据类型为GL_FLOAT,不归一化(真实物理坐标不能归一化),两个个顶点间的偏移量为0,

 

glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, 0, vertext);

glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, coord);

glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4,GL_FLOAT,GL_FALSE,0,colors);

 

 

//绘图,从下标0开始,有4个顶点

glDrawArrays(GL_TRIANGLE_STRIP,0,4);

 

}

 

2cocos2d-x中,添加C++luaScript的桥接函数,比如:

int lua_cocos2dx_3d_Skeleton3D_getBoneByName(lua_State* tolua_S)

{

    int argc = 0;

    cocos2d::Skeleton3D* cobj = nullptr;

    bool ok  = true;

 

#if COCOS2D_DEBUG >= 1

    tolua_Error tolua_err;

#endif

 

 

#if COCOS2D_DEBUG >= 1

    if (!tolua_isusertype(tolua_S,1,"cc.Skeleton3D",0,&tolua_err)) goto tolua_lerror;

#endif

 

    cobj = (cocos2d::Skeleton3D*)tolua_tousertype(tolua_S,1,0);

 

#if COCOS2D_DEBUG >= 1

    if (!cobj) 

    {

        tolua_error(tolua_S,"invalid ‘cobj‘ in function ‘lua_cocos2dx_3d_Skeleton3D_getBoneByName‘", nullptr);

        return 0;

    }

#endif

 

    argc = lua_gettop(tolua_S)-1;

    if (argc == 1) 

    {

        std::string arg0;

 

        ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.Skeleton3D:getBoneByName");

        if(!ok)

        {

            tolua_error(tolua_S,"invalid arguments in function ‘lua_cocos2dx_3d_Skeleton3D_getBoneByName‘", nullptr);

            return 0;

        }

        cocos2d::Bone3D* ret = cobj->getBoneByName(arg0);

        object_to_luaval<cocos2d::Bone3D>(tolua_S, "cc.Bone3D",(cocos2d::Bone3D*)ret);

        return 1;

    }

    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Skeleton3D:getBoneByName",argc, 1);

    return 0;

 

#if COCOS2D_DEBUG >= 1

    tolua_lerror:

    tolua_error(tolua_S,"#ferror in function ‘lua_cocos2dx_3d_Skeleton3D_getBoneByName‘.",&tolua_err);

#endif

 

    return 0;

}

 

3、面试遗留:

1luatable本身是由两块内存组成,一块是连续的array,另外一块则是hashTable实现的。因为没看过源码不确认数组这块的存储,就没有提及

2lua的调用栈从1N为栈增加,即从栈底向栈顶进发。-1为栈顶,-N为栈底。具体的内存结构还没看

3QuickSortHeapSort的确切代码,主要在于QuickSort的非递归实现。

4)认真考究cocos2d的主线线程流程,有利于以后做架构优化

 

4lua脚本调用C++,则是先压函数地址为0下标位;C++lua入栈从左参数开始入栈。C++若调用lua的函数则需要使用lua_callLua只能调用使用特定格式的函数:

定义一个C/C++函数:  

代码:typedef int (*lua_CFunction) (lua_State *L); //要求参数和返回值必须和这个一直,即可以赋值函数指针给lua_CFunction的都可以被调用

函数必须以Lua解释器作为参数,并且返回值为int类型。既然Lua解释器作为函数的参数,那么实际上函数可以从栈中取得任意多个参数。下面我 们将看到,返回的整数值代表入栈的值的数目。如果有一个C/C++函数,你想在Lua中调用他,很容易封装一下就可以满足上述要求。

 

5、上面一条成为C++粘合层,cocos2d-lua的分支就是增加了粘合层来建立lua虚拟机和C++库的连接,同时删减没必要了模块。这个粘合层在设计模式中叫做代理,早前云风曾经提到是否使用类似的设计,如果真要提供库,必须减少粘合层的厚度才能保证健壮性

lua这边的库也要实现Lua的粘合层,才能使得脚本开发时使用的是和C++类似的API

cocos的粘合层需要重新编写一边,这也是为什么自定义库需要使用luabinding等工具方便。而维护引擎必须也要熟悉cocos接口设计思想,如第3条,都会根据参数个数去实现粘合调用的是哪个接口,quick引擎组要做的事情大部分是这个吧。

 

6、以前实现的QuicklySort:在github上面有Cpp文件夹中有

void swap(int *x,int *y)

{

int temp;

temp = *x;

*x = *y;

*y = temp;

}

 

int participation(int a[],int l,int r)

{

int p = a[l];

int i = l;

int j = r+1;

while(i<j)

{

do{

i++;

}while(a[i]<=p);

do{

j--;

}while (a[j]>p);

swap(&a[i],&a[j]);

}

swap(&a[i],&a[j]);

swap(&a[l],&a[j]);

return j;

}

 

void QuicklySort(int a[],int l,int r)

{

int s = 0; 

if(l<r)

{

s = participation(a,l,r);

QuicklySort(a,l,s-1);

QuicklySort(a,s+1,r);

}

}

 

7、 










1、先记录几篇博客,供以后查看:

http://cn.cocos2d-x.org/tutorial/show?id=1474
http://blog.csdn.net/ym012/article/details/7209637
http://www.cnblogs.com/sifenkesi/p/3876745.html
http://my.oschina.net/xlplbo/blog/314956
http://blog.csdn.net/dongdongdongjl/article/details/8629704


2、本人的环境文档:链接:http://pan.baidu.com/s/1o6FROMY 密码:o7vt
直接使用源码配置。luac.c和lua.c相关说明参照:
http://blog.csdn.net/dongdongdongjl/article/details/8629704



shader实现灰度图