OpenGL實現3D自由變形

2021-08-04 04:05:33 字數 3182 閱讀 9451

筆者介紹:姜雪偉,it公司技術合夥人,it高階講師,csdn社群專家,特邀編輯,暢銷書作者,已出版書籍:《手把手教你架構3d遊戲引擎》電子工業出版社和《unity3d實戰核心技術詳解》電子工業出版社等。

以前有朋友問我,關於變形動畫是如何實現的,實現方式主要有兩種,一種是通過美術人員利用max工具自己調出動畫,這種調出的動畫太僵硬而且不能根據使用者的要求隨意變形,只能按照預先調好的動畫變形,這種做法可以排除了。第二種做法是通過程式實現自由的動畫變換,在這裡給讀者介紹利用opengl實現的變形動畫,目的是把動畫的變換原理給讀者介紹清楚。

在介紹3d變形的之前,讀者首先要掌握的是3d的固定流水線, 現在做遊戲的開發者對於什麼是3d固定流水線一無所知,市面上使用的大部分引擎都封裝的非常好,開發者也淪為了只會使用工具,對於一些常識一概不知。在遊戲公司做的主要事情就是寫寫邏輯,呼叫呼叫介面,如果需求超出介面的範疇基本上就是一籌莫展,或者說引擎的功能滿足不了。面對這種情況,作為開發者必須把3d的基本知識掌握了,這樣遇到3d的任何問題都不會感覺難下手,至少知道解決問題的思路。如果讀者對於3d固定流水線不清楚可以自己去查閱,我也寫過關於3d固定流水線的部落格,在這裡就不做介紹了,簡單的一句話表示3d固定流水線就是將3d模型在2d螢幕上顯示的過程,這個過程就是對於矩陣的換算,對應3d固定流水線是3d可程式設計流水線,不清楚的讀者自行查閱一下,這個都必須要掌握的。

接下來介紹實現變形的基本思路:

第一步,準備使用的模型,模型格式很多種,這個可以使用網上的,也可以自己編寫外掛程式實現自定義的模型。本專案對應的模型是字尾名為m的自定義的模型格式,模型格式內容如下所示:

上圖顯示的只是一部分,為了能讓讀者看清楚,並沒有對模型進行加密,為了計算方便,這裡只給出了vertex頂點和face面的資料。

第二步,定義模型的資料結構體

#ifndef halfedge_h

#define halfedge_h

#include using namespace std;

// halfedge structures

struct he_edge;

struct he_vert;

struct he_face;

struct he_line;

struct he_edge

;struct he_vert

;struct he_face

;struct he_line

he_line(){};

he_line(const he_line &vert)

he_line(unsigned int v1, unsigned int v2)

};#endif

第三步,需要載入模型,並計算頂點和麵的法線以及設定包圍盒,標頭檔案的內容給讀者展示如下:

#ifndef mesh_h

#define mesh_h

#include #include //#include #include #include #include using namespace std;

// mesh functions

void loadmesh(std::string path);

void findminmax(float tempx, float tempy, float tempz);

void calcfacenorm(void);

void calcvertnorm(void);

void settoorigin(void);

void scaletoorigin(void);

// draw functions

double editlinewidth(int width);

void drawmeshwire(void);

void drawmeshsolid(void);

void drawmeshpoint(void);

void drawbbox(void);

void drawgrid(void);

void drawaxes(void);

// dialog functions

void createfiledialog(void);

int createmsgbox(int msgboxid);

enum

;#endif

具體實現會在部落格的末尾給讀者展示。

第四步,開始對模型的變形處理,在這裡並沒有使用什麼高深的演算法,其實就是對它們的頂點進行矩陣變換。首先進行的是世界變換,投影變換,最後是視口變換。

變形的函式如下所示:

void deformmesh()

} for(int count = 0; count < numofvert; count++)

}}

當你看到**後,第一印象就是太簡單了,確實是這樣,變形其實就是將需要改變的頂點進行一系列矩陣變換,在這裡使用了opengl的庫函式介面

glpushmatrix();

gltranslatef(copyvertices[count].x, copyvertices[count].y, copyvertices[count].z);

glutsolidsphere(0.1, 20, 20);

glpopmatrix();

進行頂點的移動,同時呼叫了函式
trivariatebernstein
進行頂點的變換以及權值計算,**如下所示:

vertex trivariatebernstein(vertex vert)

} }return convertedvert;

}

沒有使用任何演算法,實現的就是模型的矩陣變換。

最後一步就是實現,首先要做的事情是選擇需要變形的頂點或者區域,使用了函式如下所示:

void moveselectedcp(int endx, int endy)

}

在再main函式中呼叫封裝的函式即可。其實做起來還是比較簡單的,就是對變形的部分做了矩陣的運算。大家關注上面加粗的部分。

CSS3 Transform變形(3D轉換)

三維變換使用基於二維變換的相同屬性,如果您熟悉二維變換,你們發現3d變形的功能和2d變換的功能相當類似。css3中的3d變換主要包括以下幾種功能函式 3d位移 css3中的3d位移主要包括translatez 和translate3d 兩個功能函式 3d旋 css3中的3d旋轉主要包括rotatex...

3D基礎 3D座標變換在OpenGL 中的實踐

在計算機圖形學中,變換矩陣是非常基礎也是非常重要的知識,在許多資料中,只是羅列出一堆矩陣公式,圖表等等,這很難給人感性的認識,特別是初學者,筆者結合 opengl 這樣乙個非常流行的圖形庫,以實踐的方式闡述在 3d變換矩陣中最簡單的三種 平移 縮放以及旋轉。這裡有一些前提知識,就是需要了解線性代數一...

OpenGL教程之向3D進軍

在上節課的內容上作些擴充套件,我們現在開始生成真正的3d物件,而不是象前兩節課中那樣3d世界中的2d物件。我們給三角形增加乙個左側面,乙個右側面,乙個後側面來生成乙個金字塔 四稜錐 給正方形增加左 右 上 下及背面生成乙個立方體。我們混合金字塔上的顏色,建立乙個平滑著色的物件。給立方體的每一面則來個...