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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章