青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

麒麟子

~~

導航

<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

統計

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

Friends

WebSites

積分與排名

最新隨筆

最新評論

閱讀排行榜

評論排行榜

irrlicht引擎:硬件蒙皮骨骼動畫

這個東西很順利,僅用了半小時就找到了方法,最應該感謝的還是Super TuxKart(簡稱STK,下面就都用這三字母了). 如果不明白STK,同時又對它感興趣的童鞋,可以訪問這里

http://supertuxkart.sourceforge.net/

由于墻的原因,需要各位搭梯子。

 

上周末,在弄換裝的時候,發現irrlicht引擎本身是不支持硬件蒙皮的,多少令人有些失望。 心里就一直尋思著怎么擴展一下,將它弄出來。

值得說明的是STK對irrlicht引擎的用法是很簡單的,基本上可以說是裸用,并未在irrlicht接口上做修改。 而是對外進行了一些必要的擴展。

當然,STK也對外開放了一個irrlicht.dll,說是修改了其中的BUG。 但直接使用irrlicht是可以的。

 

廢話不多說,來說說如何不修改irrlicht一行代碼,通過外部擴展來實現硬件骨骼動畫吧

 

首先,能夠使我們不修改irrlicht代碼的原因,是因為ISkinnedMesh提供了一個setHardwareSkinning接口,默認為false.

雖然這個接口的說明是"(This feature is not implemented in irrlicht yet)”,但并不代表,設置與不設置無差別。

查看代碼可以發現,當你設置了這個為true以后,irrlicht就完全不管你的動畫了。 意思就是,要是你非要讓我干我不干不了的事,那就只有您另請高明了。

irrlicht連CPU計算都不會參與。 這正好讓我們有機可乘,完全用GPU接管。

 

而要讓一個頂點參與骨骼計算,那骨骼索引則是少不了的。所以,我們需要想辦法讓頂點數據能夠將骨骼索引代入SHADER中。

在STK中用了一種巧妙的方法, 就是使用了頂點的顏色數據, 雖然這樣一來,頂點顏色就用不了了。 但在模型渲染時,頂點顏色很少被使用到的。 也就是說,頂點顏色在STK的動畫模型中,被用作了骨骼索引。

初始化骨骼索引的方法很簡單,用下面的代碼遍歷即可。

設:我們有一個骨骼動畫模型是 ISkinnedMesh* pSkinnedMesh = …

那么:初始化代碼如下

for(u32 i = 0;i < pSkinnedMesh ->getMeshBuffers().size();++i)
{
    for(u32 g = 0;g < pSkinnedMesh ->getMeshBuffers()[i]->getVertexCount();++g)
    {
        pSkinnedMesh ->getMeshBuffers()[i]->getVertex(g)->Color = video::SColor(0,0,0,0);
    }
}

//初始化完畢以后,就是需要真正的索引賦值了,通過以下代碼可以完成

const core::array<scene::ISkinnedMesh::SJoint*>& joints = pSkinnedMesh ->getAllJoints();
for(u32 i = 0;i < joints.size();++i)
{
    const core::array<scene::ISkinnedMesh::SWeight>&    weights = joints[i]->Weights;
    for(u32 j = 0;j < weights.size();++j)
    {
        int buffId = weights[j].buffer_id;

        int vertexId = pSkinedMesh->getAllJoints()[i]->Weights[j].vertex_id;
        video::SColor* vColor = &pSkinedMesh->getMeshBuffers()[buffId]->getVertex(vertexId)->Color;

        if(vColor->getRed() == 0)
            vColor->setRed(i + 1);
        else if(vColor->getGreen() == 0)
            vColor->setGreen(i + 1);
        else if(vColor->getBlue() == 0)
            vColor->setBlue(i + 1);
        else if(vColor->getAlpha() == 0)
            vColor->setAlpha(i + 1);
    }
}

 

//經過以上兩個步驟,頂點數據改造完成。 值得注意的是, 在這里, 索引 0 是被認為是無效的

 

然后,我們來創建一個SHADER作為渲染。

假設 我們將這個pSkinnedMesh綁定了到了一個IAnimatedSceneNode* node 上。

那,我們為這個結點創建一個材質 在創建材質前,我們需要準備一個SHADER回調。 SHADER回調就像下面一樣就可以了。

class HWSkinCallBack:public video::IShaderConstantSetCallBack
{
    scene::IAnimatedMeshSceneNode* m_pNode;
public:
    HWSkinCallBack(scene::IAnimatedMeshSceneNode* node):m_pNode(node)
    {

    }
    virtual void OnSetConstants(video::IMaterialRendererServices* services,
        s32 userData)
    {
        scene::ISkinnedMesh* mesh = (scene::ISkinnedMesh*)m_pNode->getMesh();
        f32 joints_data[55 * 16];
        int copyIncrement = 0;

        const core::array<scene::ISkinnedMesh::SJoint*> joints = mesh->getAllJoints();
        for(u32 i = 0;i < joints.size();++i)
        {
            core::matrix4 joint_vertex_pull(core::matrix4::EM4CONST_NOTHING);
            joint_vertex_pull.setbyproduct(joints[i]->GlobalAnimatedMatrix, joints[i]->GlobalInversedMatrix);

            f32* pointer = joints_data + copyIncrement;
            for(int i = 0;i < 16;++i)
                *pointer++ = joint_vertex_pull[i];

            copyIncrement += 16;
        }

        services->setVertexShaderConstant("JointTransform", joints_data, mesh->getAllJoints().size() * 16);
    }
};

 

好了,現在我們來創建一個材質

s32 hwskm = gpu->addHighLevelShaderMaterialFromFiles(
        "../../skinning.vert","main",video::EVST_VS_2_0,
        "","main",video::EPST_PS_2_0,&hwc,video::EMT_SOLID);

//用新創建出來的材質賦值給這個結點

node->setMaterialType((video::E_MATERIAL_TYPE)hwskm );

 

//到此,設置完畢。

//最后,就是skinning.vert本身的內容了。 貼出來即可,沒有太多技巧,就是一個普通的蒙皮。

// skinning.vert

#define MAX_JOINT_NUM 36
#define MAX_LIGHT_NUM 8

uniform mat4 JointTransform[MAX_JOINT_NUM];

void main()
{
    int index;
    vec4 ecPos;
    vec3 normal;
    vec3 light_dir;
    float n_dot_l;
    float dist;

    mat4 ModelTransform = gl_ModelViewProjectionMatrix;
    index = int(gl_Color.r * 255.99);
    mat4 vertTran = JointTransform[index - 1];
    index = int(gl_Color.g * 255.99);
    if(index > 0)
        vertTran += JointTransform[index - 1];

    index = int(gl_Color.b * 255.99);
    if(index > 0)
        vertTran += JointTransform[index - 1];
    index = int(gl_Color.a * 255.99);
    if(index > 0)
        vertTran += JointTransform[index - 1];
    ecPos = gl_ModelViewMatrix * vertTran * gl_Vertex;
    normal = normalize(gl_NormalMatrix * mat3(vertTran) * gl_Normal);
    gl_FrontColor = vec4(0,0,0,0);
    for(int i = 0;i < MAX_LIGHT_NUM;i++)
    {
        light_dir = vec3(gl_LightSource[i].position-ecPos);
        n_dot_l = max(dot(normal, normalize(light_dir)), 0.0);
        dist = length(light_dir);
        n_dot_l *= 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist);
        gl_FrontColor += gl_LightSource[i].diffuse * n_dot_l;
    }
    gl_FrontColor = clamp(gl_FrontColor,0.3,1.0);

    ModelTransform *= vertTran;
    gl_Position = ModelTransform * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_TexCoord[1] = gl_MultiTexCoord1;
    /*
    // Reflections.
    vec3 r = reflect( ecPos.xyz , normal );
    float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
    gl_TexCoord[1].s = r.x/m + 0.5;
    gl_TexCoord[1].t = r.y/m + 0.5;
    */
}

 

 

//注:這是GLSL 2.0, 在用IRR做測試的時候,要選GL驅動方式。

 

還是上個圖吧,不上圖感覺沒有真像。 雖然圖看不出來什么動作

image

為了說明它真的在動,不得不上第二張。

 

image 

 

在此,十分感謝Super Tux Kart. 提供了一個學習和擴展irrlicht的榜樣.

posted on 2013-03-26 00:08 麒麟子 閱讀(3362) 評論(0)  編輯 收藏 引用 所屬分類: Game and EngineIrrlicht

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜视频一区| 久久久久久久综合色一本| 欧美系列一区| 国产精品分类| 国产伦精品一区二区三区视频孕妇 | 国产一区二区日韩精品| 国产亚洲一级| 亚洲国产精品美女| 中文av一区特黄| 久久精品中文字幕一区| 美女久久一区| 亚洲精品乱码久久久久久日本蜜臀 | 国产亚洲人成a一在线v站| 在线不卡亚洲| 夜夜嗨av一区二区三区四季av| 久久国产视频网| 欧美国产乱视频| 国产精品一香蕉国产线看观看 | 午夜精品久久久久久久久久久久久 | 免费91麻豆精品国产自产在线观看| 欧美成人福利视频| 中日韩男男gay无套 | 国产伦精品一区二区三区四区免费 | 久久大香伊蕉在人线观看热2| 美女国产一区| 国产酒店精品激情| 日韩一二三区视频| 久久三级福利| 亚洲视频一二区| 免费在线观看日韩欧美| 欧美午夜国产| 亚洲欧洲另类| 久久久久久久久久久久久9999| 亚洲欧洲综合另类| 久久久青草青青国产亚洲免观| 国产精品99一区二区| 亚洲人成人一区二区三区| 久久激情五月婷婷| 一区二区三区成人精品| 欧美第一黄网免费网站| 激情综合网址| 久久精品国产一区二区电影| 日韩一级精品视频在线观看| 久久亚洲欧美国产精品乐播| 国产精品久久久久毛片软件| 亚洲美女av黄| 欧美国产免费| 久久亚洲精品伦理| 国产综合欧美| 久久全国免费视频| 欧美中文字幕在线播放| 国产欧美日韩在线| 欧美一区二区在线免费观看| 一本一道久久综合狠狠老精东影业 | 亚洲主播在线| 久久久久久久一区| 国产精品中文字幕欧美| 亚洲一区二区3| 91久久精品国产91久久| 欧美成人首页| 亚洲美女一区| 亚洲精品国产精品乱码不99按摩| 免费看的黄色欧美网站| 亚洲国产电影| 亚洲国产影院| 欧美三级视频在线| 亚洲欧美国产日韩天堂区| 妖精成人www高清在线观看| 欧美日韩一二三区| 亚洲欧美日韩一区二区三区在线观看| 一区二区三区日韩欧美精品| 国产精品久久看| 久久激情五月激情| 久久久久国产一区二区三区| 亚洲高清精品中出| 亚洲精品在线看| 国产精品美女一区二区| 久久成人18免费观看| 久久久999精品免费| 亚洲国产成人av好男人在线观看| 欧美福利在线| 欧美日韩在线三区| 久久精品视频在线看| 免费视频亚洲| 亚洲主播在线播放| 久久久久久网| 在线视频免费在线观看一区二区| 一区二区三区色| 国模一区二区三区| 亚洲日本中文字幕| 国产精品午夜春色av| 久久婷婷影院| 欧美日韩在线不卡一区| 久久久九九九九| 欧美激情1区2区| 欧美亚洲专区| 欧美高潮视频| 久久精品国产一区二区三区免费看| 久久九九免费视频| 亚洲一区影音先锋| 美女久久网站| 亚洲综合精品一区二区| 久久综合给合| 欧美一区日韩一区| 欧美久久视频| 米奇777超碰欧美日韩亚洲| 欧美日韩精品免费看| 麻豆精品国产91久久久久久| 欧美日韩欧美一区二区| 蜜臀av一级做a爰片久久| 国产精品视频自拍| 亚洲日韩欧美视频一区| 一区二区在线观看视频在线观看| 一本久久综合亚洲鲁鲁五月天| 在线欧美亚洲| 久久av在线看| 午夜亚洲一区| 性欧美xxxx大乳国产app| 亚洲国产成人午夜在线一区| 夜夜嗨av一区二区三区中文字幕 | 免费久久99精品国产| 国产精品久久久久永久免费观看| 亚洲国产精品激情在线观看| 一区二区三区在线观看欧美| 亚洲欧美在线磁力| 欧美一级电影久久| 国产精品美女一区二区在线观看| 91久久久一线二线三线品牌| 最新高清无码专区| 麻豆精品国产91久久久久久| 老司机免费视频一区二区| 国产一区二区三区四区三区四| 亚洲永久在线观看| 性色av香蕉一区二区| 国产欧美在线看| 香港久久久电影| 久久国产精彩视频| 国产午夜亚洲精品理论片色戒| 亚洲免费视频观看| 香蕉免费一区二区三区在线观看 | 国产精品视频久久一区| 日韩图片一区| 亚洲欧美日本国产有色| 国产精品久久久久久久久果冻传媒 | 99亚洲一区二区| 亚洲性视频h| 国产精品亚洲综合天堂夜夜| 亚洲欧美成人综合| 久久久久亚洲综合| 亚洲国产日韩欧美在线99| 欧美成人免费在线视频| 亚洲美女啪啪| 香蕉乱码成人久久天堂爱免费| 国产女精品视频网站免费| 久久激情婷婷| 亚洲高清视频的网址| 亚洲色诱最新| 国内精品久久久| 欧美大片专区| 亚洲天堂av图片| 久久久精品五月天| 亚洲电影免费| 欧美视频1区| 久久精品一区蜜桃臀影院| 亚洲国产欧美不卡在线观看| 亚洲图片欧美一区| 国语自产精品视频在线看| 欧美成年人视频网站欧美| 一区二区三区成人| 美女网站在线免费欧美精品| 亚洲午夜av| 黄色综合网站| 国产精品久久久久99| 美日韩免费视频| 亚洲伊人伊色伊影伊综合网| 蜜臀久久久99精品久久久久久| 久久久999精品视频| 国产女人精品视频| 蜜桃久久精品乱码一区二区| 9久草视频在线视频精品| 久久亚洲私人国产精品va| 亚洲精选国产| 国产手机视频一区二区| 欧美精品二区| 久久精品日韩一区二区三区| 99国产一区| 女人色偷偷aa久久天堂| 亚洲欧美国产另类| 99视频在线观看一区三区| 韩国三级在线一区| 国产精品久久久久久影院8一贰佰| 久久综合九九| 欧美在线观看一二区| 一区二区精品在线观看| 91久久精品国产91久久性色| 久久久久se| 久久精品首页| 久久精品视频在线观看| 欧美在线免费播放| 亚洲一区观看|