1. 程式人生 > >cocos2D-X原始碼分析之從cocos2D-X學習OpenGL(20)----模型,網格和材質

cocos2D-X原始碼分析之從cocos2D-X學習OpenGL(20)----模型,網格和材質

       openGL在cocos2d-x中的應用點,呼叫的api基本已經介紹的差不多了,這一篇介紹一些3d遊戲中的概念,它們也和底層有一些關係,也是遊戲中常用的一些封裝。

       當我們要在螢幕上繪製簡單的圖形時,我們直接計算點的座標就可以,但是遊戲世界中經常有些複雜的模型,例如房子汽車等,這些模型一般是用建模工具製作出來,並且匯出資料到指定檔案中,然後我們遊戲中在讀取檔案把模型渲染出來,一般比較有名的建模工具包括3dmax,maya等等,推薦一個免費建模工具-blender,文件和教程也都比較多,也相對輕量化,程式設計師們都可以嘗試一下,地址:https://www.blender.org/,中文社群:http://www.blendercn.org/。

       關於cocos2d-x讀取3d模型檔案的方法之前也都介紹過,這裡不再贅述,可以參考文章:http://blog.csdn.net/bill_man/article/details/48396719,我們用Spirte3D這個類來讀取相關的模型,並在遊戲中使用,它的使用方式和正常的node一樣

auto ship = Sprite3D::create("Sprite3DTest/boss1.obj");
ship->setScale(5);
ship->setTexture("Sprite3DTest/boss.png");
ship->setNormalizedPosition(Vec2(.5,.5));
ship->setRotation3D(Vec3(90,0,0));
ship->setForceDepthWrite(true);
       目前的Spirte3D功能已經相對完整了,還包含非同步載入等功能,觀察Spirte3D的原始碼,我們發現組成它的除了骨骼外,還有一個叫網格的(Mesh),這是一個3d模型的基本單位,一個模型可能有多個網格組成:
Skeleton3D*                  _skeleton; //骨骼
Vector<MeshVertexData*>      _meshVertexDatas;//網格資料
std::unordered_map<std::string, AttachNode*> _attachments;
BlendFunc                    _blend;//混合方法
Vector<Mesh*>              _meshes;//網格
        一個網格就是一個模型的繪製單位,網格資料包含貼圖資訊和頂點資訊,在cocos2d-x的網格類中包含面板,光照uniform等資訊,可以通過getMeshByIndex或者getMeshByName等方法獲得具體的網格,可以對模型的部分網格進行特定的操作從而達到特定的效果,例如可以控制某個網格的顯示與否:

_sprite3d->getMeshByName("Girl_UpperBody02")->setVisible(false);

       材質是一個集合概念,它包含色彩,紋理,光照的反射率等等,甚至包含使用的shader檔名等等,它讓我們不用使用硬編碼去實現不同的渲染效果,cocos2d-x中使用Properties和Material類定義材質:

//定義材質
auto properties = Properties::createNonRefCounted("Materials/auto_binding_test.material#sample");
PrintProperties(properties, 0);
Material *mat1 = Material::createWithProperties(properties);
//使用材質
auto spriteBlur = Sprite::create("Images/grossini.png");
spriteBlur->setNormalizedPosition(Vec2(0.2f, 0.5f));
this->addChild(spriteBlur);
spriteBlur->setGLProgramState(mat1->getTechniqueByName("blur")->getPassByIndex(0)->getGLProgramState());
       材質是這樣一個概念,它好比你模型的“衣服”,定義著你的模型的顯示,卻不能單獨的顯示,必須附著在模型上才有效。
technique blur{
    pass 0
    {
	shader
	{
	     defines = THIS_IS_AN_EXAMPLE 1;TOMORROW_IS_HOLIDAY 2
	     vertexShader = Shaders/example_Simple.vsh
	     fragmentShader = Shaders/example_Blur.fsh
	     // Uniforms
	     sampleNum = 5
	     resolution = 100,100
	     // auto bindings
	     blurRadius = DYNAMIC_RADIUS
        }
    }
}
        上面就是一個材質,它定義了shader檔案,也定義了一些傳給shader的uniform值,實現了邏輯和引數的分離,使得shader可以被重用。

        能力不足,水平有限,如有錯誤,歡迎指出。