<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          代碼吸貓 | 用 OpenGL 圖像渲染的養(yǎng)貓計(jì)劃

          共 986字,需瀏覽 2分鐘

           ·

          2021-11-13 16:38

          在掘金上看到最近的新活動(dòng) "代碼吸貓",技術(shù)類文章只要和貓有關(guān)就行。

          對(duì)于沒有養(yǎng)貓的程序員,這不是為難人嘛。

          不過沒關(guān)系,用 OpenGL 圖像渲染給自己造一只貓吧?。?!

          模型構(gòu)造

          首先需要構(gòu)造出貓的模型,有能力的話可以直接在三維軟件里面造一個(gè)。

          或者像我一樣直接下載免費(fèi)的貓模型,然后把它導(dǎo)入 Blender 3D 軟件中。

          在 Blender 中可以預(yù)覽貓模型,或者對(duì)它做一下調(diào)整,最后在把這個(gè)模型導(dǎo)出。

          模型加載

          導(dǎo)出的 ?obj 文件里面就記錄了模型的頂點(diǎn)信息,接下來就要用 OpenGL 將它繪制出來。

          這里要用到 assimp 開源庫(kù),它支持多種模型文件的解析操作,通過它將模型解析成一個(gè)個(gè) Mesh 。

          Mesh 的定義如下:

          class?Mesh?{
          public:
          ??/*??Mesh?Data??*/
          ??vector?vertices;
          ??vector<unsigned?int>?indices;
          ??vector?textures;
          ??unsigned?int?VAO;
          ??//?省略部分代碼
          }

          Mesh 相當(dāng)于繪制模型上的一個(gè)個(gè)網(wǎng)格或者說面片,它包含了該網(wǎng)格的頂點(diǎn)、紋理信息和繪制索引。

          而模型 Model 就是由這一系列網(wǎng)格 Mesh 組成的。

          如上圖所示,貓模型是由一個(gè)個(gè)小矩陣組成的,小矩陣就可以理解成 mesh 網(wǎng)格了。

          Model 的定義如下:

          class?Model
          {

          public:
          ??/*??Model?Data?*/
          ??vector?textures_loaded;????
          ??vector?meshes;
          ??//?省略部分代碼??
          }??

          在實(shí)際繪制的時(shí)候,也是由一個(gè)一個(gè) Mesh 最終繪制成的。

          ????//?draws?the?model,?and?thus?all?its?meshes
          ?void?Draw(Shader?shader)
          ?
          {
          ???for(unsigned?int?i?=?0;?i??????meshes[i].Draw(shader);
          ?}

          從圖中也可以看到,貓模型的網(wǎng)格數(shù)量是很多的,導(dǎo)致加載的時(shí)候會(huì)很很慢了,加載方法如下:

          ??void?loadModel(string?const?&path)
          ??
          {
          ????//?使用?assimp?庫(kù)進(jìn)行加載
          ????const?aiScene*?scene?=?importer.ReadFile(path,?aiProcess_Triangulate?|?aiProcess_FlipUVs?|?aiProcess_CalcTangentSpace);
          ????//?檢查是否有錯(cuò)
          ????if(!scene?||?scene->mFlags?&?AI_SCENE_FLAGS_INCOMPLETE?||?!scene->mRootNode)?//?if?is?Not?Zero
          ????{
          ??????cout?<"ERROR::ASSIMP::?"?<endl;
          ??????return;
          ????}
          ????//?獲取模型所在文件夾
          ????directory?=?path.substr(0,?path.find_last_of('/'));

          ????//?從根節(jié)點(diǎn)一個(gè)一個(gè)節(jié)點(diǎn)開始處理
          ????processNode(scene->mRootNode,?scene);
          ??}

          使用 assimp 處理后會(huì)得到一個(gè)根節(jié)點(diǎn),然后順著根節(jié)點(diǎn)一個(gè)一個(gè)往下處理就好了。

          ??void?processNode(aiNode?*node,?const?aiScene?*scene)
          ??
          {
          ????for(unsigned?int?i?=?0;?i?mNumMeshes;?i++)
          ????{
          ??????aiMesh*?mesh?=?scene->mMeshes[node->mMeshes[i]];
          ??????//?處理得到的?aiMesh?并組裝成定義好的?Mesh?數(shù)據(jù)結(jié)構(gòu)?
          ??????meshes.push_back(processMesh(mesh,?scene));
          ????}
          ????//?處理子節(jié)點(diǎn)
          ????for(unsigned?int?i?=?0;?i?mNumChildren;?i++)
          ????{
          ??????processNode(node->mChildren[i],?scene);
          ????}
          ??}

          可以看到處理過程大量的 for 循環(huán)操作,所以后續(xù)才會(huì)針對(duì)模型文件的優(yōu)化,加快其加載速度。

          模型渲染

          得到了最終的 Model 之后,就可以對(duì)它做渲染顯示了。

          ????//?model?矩陣調(diào)整模型顯示位置和方向
          ????glm::mat4?model?=?glm::mat4(1.0f);
          ????model?=?glm::translate(model,?glm::vec3(tranx_x,?tranx_y,?tranx_z));
          ????model?=?glm::rotate(model,glm::radians(90.0f),glm::vec3(0.0,0.0,1.0));
          ????model?=?glm::scale(model,?glm::vec3(0.5f,?0.5f,?0.5f));????
          ????shader.setMatrix4fv("model",?glm::value_ptr(model));
          ????ourModel.Draw(shader);

          由于模型自身就帶了一個(gè)位置和方向,顯示的時(shí)候不一定是我們想要的觀察方位,所以還是要調(diào)整一個(gè)模型矩陣。

          最后渲染就可以看到 貓模型 效果啦。

          小結(jié)

          為了便于觀察,可以處理一下鍵盤或者鼠標(biāo)事件,修改模型矩陣的值,從不同角度擼貓。

          目前的貓模型還只是靜態(tài)的,調(diào)整的話也只能用鍵盤調(diào)整,而且還只是改了 移動(dòng)、縮放、旋轉(zhuǎn)這些屬性,貓本身是沒有動(dòng)的。

          想要貓自身能動(dòng)的話,還需要模型里面有對(duì)應(yīng)的骨骼動(dòng)畫才可以了,等后面有了這樣的模型,再繼續(xù)迭代 。

          OpenGL 相關(guān)的文章歡迎閱讀:

          OpenGL 系列---基礎(chǔ)繪制流程
          OpenGL 學(xué)習(xí)系列---基本形狀的繪制
          OpenGL 學(xué)習(xí)系列---坐標(biāo)系統(tǒng)
          OpenGL 學(xué)習(xí)系列---投影矩陣
          OpenGL 學(xué)習(xí)系列 --- 紋理
          OpenGL 學(xué)習(xí)系列---觀察矩陣
          OpenGL 的 glDrawElements ?繪制方法
          OpenGL 3D 模型加載和渲染
          OpenGL ES 學(xué)習(xí)資源分享
          用 OpenGL 對(duì)視頻幀內(nèi)容進(jìn)行替換
          OpenGL 中的顏色混合和使用
          OpenGL 優(yōu)化項(xiàng)之面剔除和注意點(diǎn)
          OpenGL 深度測(cè)試與精度值的那些事
          OpenGL 之 EGL 使用實(shí)踐
          OpenGL 之 幀緩沖 ?使用實(shí)踐
          OpenGL 之 GPUImage 源碼分析
          OpenGL 實(shí)踐之貝塞爾曲線繪制
          OpenGL 實(shí)現(xiàn)視頻編輯中的轉(zhuǎn)場(chǎng)效果


          技術(shù)交流,歡迎加我微信:ezglumes ,拉你入技術(shù)交流群。

          私信領(lǐng)取相關(guān)資料

          推薦閱讀:

          音視頻開發(fā)工作經(jīng)驗(yàn)分享 || 視頻版

          OpenGL ES 學(xué)習(xí)資源分享

          開通專輯 | 細(xì)數(shù)那些年寫過的技術(shù)文章專輯

          NDK 學(xué)習(xí)進(jìn)階免費(fèi)視頻來了

          你想要的音視頻開發(fā)資料庫(kù)來了

          推薦幾個(gè)堪稱教科書級(jí)別的 Android 音視頻入門項(xiàng)目

          覺得不錯(cuò),點(diǎn)個(gè)在看唄~

          瀏覽 64
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美精品免费在线观看 | 中文日逼| 肏屄网视频 | 亚洲视频在线视频播放 | 福利黄色|