shader实现灰度图

1、cocos主线程以及Auto-batching

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

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

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

glview->pollEvents();

drawScene:

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

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

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

4)visit通知窗口

5)渲染,切换缓存区

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

遍历结束后执行Render():

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

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

_batchedQuadCommands缓存池不断添加单个QuadCommand,

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

其余绘制类型如custom、batchNode则是直接执行,不执行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 ) 是RGB转YUV的参数值,生成灰色图
\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() 纹理在内存或显存中存储的下标(应该是下标,我没看纹理加载,还不了解GPU和CPU的通信)

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);

}

2、cocos2d-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、面试遗留:

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

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

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

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

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

定义一个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

时间: 2024-11-18 07:44:31

shader实现灰度图的相关文章

cocos2dx shader实现灰度图android后台切换回来导致图像偏移的问题

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

Unity Shaders and Effects Cookbook (2-4) 压缩和混合纹理贴图:使用灰度图存储插值信息

这一节看了几次才慢慢的读懂. 首先是这个灰度图,为什么叫灰度图,是因为 这个图片中的 R.G.B 存放的都是同一份数据,打开Unity 来调一下颜色看看 更直观. 可以看到,当 R.G.B 三个值相同的时候,图片是只有黑白,而丢失了其它的颜色的,所以我们叫灰度图. 什么时候用到灰度图? 本文转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 比如说高度图,在这个坐标的点,海拔高,就记作 1,海拔低就记作0 .把这一份数据 同时存储到

opencv将图像转化为灰度图,然后边缘检测

1:代码如下: #include "stdafx.h" #include "highgui.h" #include "cv.h" #include "iostream" using namespace std; IplImage* doCanny(IplImage* in,double lowThresh,double highThresh,double aperture) { if(in->nChannels !=1)

【python】RGB图片到灰度图的转换

在做立体匹配求深度图的时候遇到这个问题,用惯了matlab的rgb2gray,倒是不熟悉python的实现,在网上找到了相关方案,记下来已作备用 RGB到灰度图转换公式: Y' = 0.299 R + 0.587 G + 0.114 B 自定义转换函数: 1 import numpy as np 2 3 def rgb2gray(rgb): 4 return np.dot(rgb[...,:3], [0.299, 0.587, 0.144]) 调用: 1 grayPic = rgb2gray(r

从视频文件中读入数据--&gt;将数据转换为灰度图--&gt;对图像做candy边缘检测

//从视频文件中读入数据-->将数据转换为灰度图-->对图像做candy边缘检测 //作者:sandy //时间:2015-10-10 #include <cv.h> #include <highgui.h> int main(int argc, char *argv[]){ //预备工作 CvCapture* capture=cvCreateFileCapture("E:\\Videos\\xx.avi");//让capture变量指向视频文件 i

mupdf实现常用图片转换为灰度图pnm

我要实现的工作是使用mupdf库转换pdf.jpeg.tif等文件为灰度图,转换完成的灰度图存放到内存中,而不是存为文件,在读取到内存中,主要是嵌入式系统中使用.下面是example.c,我加了我理解的注释,以及自己修改的地方.example.c全文 #include <mupdf/fitz.h> void render(char *filename, int pagenumber, int zoom, int rotation) { // Create a context to hold t

Java 彩色图转灰度图

1. 方法1 BufferedImage grayImage = new BufferedImage(width, height, colorImage.TYPE_BYTE_GRAY); Graphics g = grayImage.getGraphics(); g.drawImage(colorImage, 0, 0, null); g.dispose(); 2. 方法2(不推荐) ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRA

OprenCV学习之路一:将彩色图片转换成灰度图

//将一张彩色图片转成灰度图: //////////////////////////// #include<cv.h> #include<cvaux.h> #include<highgui.h> #include<ml.h> #include<iostream> using namespace std; using namespace cv; int main() { IplImage *src=0; src=cvLoadImage("

灰度图转彩色图(伪彩色处理)

将8Bit灰度数据转化为Bgr24的彩色图像 8bit灰度数据:byte[] GrayValue    长度:width * height PixelFormat pixelFormat = PixelFormats.Bgr24; byte[] colorvalues = GrayToColor(GrayValue); ByteSize = Width * Height; IntPtr dataPtr = IntPtr.Zero; GCHandle _hObject = GCHandle.All