OpenGL学习之路(二)
1 引子
在上一篇讀書筆記中,我們對(duì)書本中給出的例子進(jìn)行詳細(xì)的分析。首先是搭出一個(gè)框架;然后填充初始化函數(shù),在初始化函數(shù)中向OpenGL提供頂點(diǎn)信息(緩沖區(qū)對(duì)象)和頂點(diǎn)屬性信息(頂點(diǎn)數(shù)組對(duì)象),并啟用頂點(diǎn)數(shù)組對(duì)象;最后填充繪制函數(shù),首先清空顏色緩存,然后調(diào)用glDrawArray來繪制基本圖形。例子中使用的坐標(biāo)都是二維坐標(biāo),所以畫出來的圖形是二維圖形(這里是兩個(gè)三角形),而我們知道OpenGL最主要是用來進(jìn)行三維圖形的渲染的,所以有必要在學(xué)習(xí)OpenGL相關(guān)API之前對(duì)三維變換做一個(gè)簡要的介紹。其實(shí)這一部分應(yīng)該屬于紅寶書中第五章的內(nèi)容,這里我們將其提前了,在讀書筆記(二)就拿出來介紹——這是我們?nèi)S渲染的最基本的知識(shí)點(diǎn),也是最關(guān)鍵的知識(shí)點(diǎn),理解起來也有一定的難度。本次讀書筆記主要講述平移、旋轉(zhuǎn)、縮放變換的變換矩陣,投影變換將在下一篇讀書筆記再做記錄。本篇讀書筆記主要是自己對(duì)一些數(shù)學(xué)概念的理解和記錄,僅供參考,如有不同理解的,大家可以一起討論哈!
2 點(diǎn)、坐標(biāo)系與向量
討論三維變換之前,得先了解點(diǎn)、向量和坐標(biāo)系這些基本數(shù)學(xué)概念。這部分內(nèi)容可能比較抽象,下面記錄的是我對(duì)這些概念的一些理解。
2.1 位置的相對(duì)性
在日常生活中,我們?cè)谙騽e人描述一個(gè)陌生的地方的時(shí)候,通常會(huì)選擇一個(gè)他熟悉的地方作為一個(gè)參考點(diǎn)。例如:我們向老外介紹河北的一座古城邯鄲,老外知道北京,我們就會(huì)說邯鄲在北京往西南走300km;如果老外知道石家莊,那我們也可以告訴他,邯鄲在石家莊往南走100km。這說明,位置是一個(gè)相對(duì)的概念,要描述一個(gè)位置,首先要選擇參考點(diǎn);參考點(diǎn)的選擇是任意的,所選取的參考點(diǎn)不同,位置的描述也就不同。
在幾何中,位置用“點(diǎn)”這一概念來描述,即點(diǎn)是一個(gè)只有位置沒有大小的量。描述一個(gè)點(diǎn)和描述一個(gè)位置是一回事,剛才已經(jīng)說了位置是一個(gè)相對(duì)的概念,所以首先就要用到參考點(diǎn)。我們以最簡單的一維數(shù)軸為例來說明描述點(diǎn)的位置,如下圖所示:
對(duì)于數(shù)軸上同一點(diǎn)$A$,要描述$A$點(diǎn)的位置,先要選取任意一個(gè)參考點(diǎn),如果選擇的參考點(diǎn)是$O_1$,則$A$點(diǎn)在$O_1$點(diǎn)右邊$l_1$的地方;如果選擇的參考點(diǎn)是$O_2$,則$A$點(diǎn)在$O_2$點(diǎn)左邊$l_2$的地方。通過數(shù)軸和參考點(diǎn),我們就將數(shù)軸上的幾何點(diǎn)用抽象的數(shù)字表達(dá)出來了。
2.2 坐標(biāo)系與向量
從圖上可以看出,數(shù)軸上的點(diǎn)只能沿著數(shù)軸方向進(jìn)行變化,即它是一維的。如果點(diǎn)在一個(gè)平面上或一個(gè)空間中變化,那么數(shù)軸這一工具是無法描述的。這時(shí)就要引入二維坐標(biāo)系和三維坐標(biāo)系來描述點(diǎn)的位置。介紹坐標(biāo)系之前,首先介紹一下向量的概念。
在我們還是十七八歲學(xué)習(xí)高一幾何的時(shí)候,我們就已經(jīng)接觸到了向量——既有大小,又有方向的量,用一個(gè)有向線段來表示。說白了,向量定義了一個(gè)方向、一個(gè)長度和一個(gè)單位長度。如上圖中,$O_1A$和$AO_2$就是兩個(gè)向量,大小分別為$l_1$和$l_2$,方向?yàn)樗较蛴摇?/span>
一個(gè)平面上,有無數(shù)這樣的向量。但是關(guān)于向量,有一個(gè)非常重要的法則——使用平行四邊形法則來對(duì)任何一個(gè)向量進(jìn)行分解。平行四邊形法則來自于物理學(xué)中力的分解與合成,后被引入數(shù)學(xué)中加以抽象來描述向量的分解與合成。所謂平行四邊形法則,指的是任何一個(gè)平面向量都可以用一個(gè)不共線的兩個(gè)向量表示。于是,平面中無數(shù)的向量就可以用兩個(gè)不共線的向量來表示。由這兩個(gè)向量及它們的公共起點(diǎn)構(gòu)成的數(shù)學(xué)結(jié)構(gòu)就是二維坐標(biāo)系,用坐標(biāo)系就可以描述二維平面上的任意點(diǎn),當(dāng)然也可以描述二維平面上的任意向量,這兩個(gè)向量就是線性代數(shù)中的基向量。我們知道,在數(shù)學(xué)中,向量是位置無關(guān)的(即自由向量),只要大小相等,方向相同的兩個(gè)向量就是同一個(gè)向量(這和物理學(xué)中的力不一樣)。所以要描述二維空間中的點(diǎn),還需要一個(gè)參考點(diǎn),于是就定義了這兩個(gè)向量的公共起點(diǎn)作為參考點(diǎn)——即我們熟知的坐標(biāo)原點(diǎn)。坐標(biāo)軸向量和坐標(biāo)原點(diǎn)就構(gòu)成了坐標(biāo)系,可以用坐標(biāo)系來描述其中的任何向量和任一點(diǎn)。
三維坐標(biāo)系和二維坐標(biāo)系是類似的,使用兩次平行四邊形法則,從而將任意一個(gè)三維向量表示為三個(gè)不共面的三維向量(基向量)來表示,這三個(gè)向量移到一起的公共起點(diǎn)定義為三維坐標(biāo)系的坐標(biāo)原點(diǎn)。二維和三維笛卡爾坐標(biāo)系就是基向量垂直的二維和三維坐標(biāo)系,也是應(yīng)用最為廣泛的坐標(biāo)系,也稱為平面直角坐標(biāo)系和空間直角坐標(biāo)系。
下面,我們來看看向量的表示方法。同樣在我們懵懵懂懂的青春歲月里,我們就已經(jīng)知道向量有兩種表示方法:第一種是符號(hào)表示法,如$\mathbf{a}, \mathbf{b}$等;另一種是坐標(biāo)表示法,這里對(duì)坐標(biāo)表示做較詳細(xì)的說明。剛才已經(jīng)說了,任意一個(gè)二維向量都可以用兩個(gè)不共線的向量來表示,假設(shè)兩個(gè)基向量為$\mathbf{i}$和$\mathbf{j}$,且長度為1。則對(duì)任一個(gè)向量$\mathbf{a}=x_a\mathbf{i} + y_a\mathbf{j}$,這樣,向量$\mathbf{a}$可用一個(gè)有序?qū)?(x_a, y_a)$來唯一表示,這就是向量的坐標(biāo)表示。三維乃至$N$維向量的坐標(biāo)表示都是一樣的。在這里,博主還是想強(qiáng)調(diào)一下,向量的坐標(biāo)并不是該向量在坐標(biāo)軸上的投影,只有笛卡爾坐標(biāo)是向量在基向量上的投影。所以,在普通坐標(biāo)系下,一個(gè)向量的坐標(biāo)不是很好求,但在直角坐標(biāo)系下,就變得很好求了——求投影,這也是笛卡爾坐標(biāo)系應(yīng)用的如此廣泛的原因。下面我們來看看,什么是投影,其實(shí)高一數(shù)學(xué)中也已經(jīng)接觸到了,如下圖所示:
假設(shè)$c$為向量$\mathbf{a}$在向量$\mathbf{b}$上的投影,那么:
\begin{equation} c = \mathbf{a} \cos<\mathbf{a},?\mathbf{b}>\end{equation}
所以,在二維直角坐標(biāo)系中,如果二維向量$\mathbf{a}$長度為$l$,該向量與$x$軸和$y$軸的夾角分別為$\alpha$和$\beta$,則我們很容易得到該向量的坐標(biāo)表示為$\mathbf = (l\cos\alpha, l\cos\beta)^\text{T}$;同樣地,對(duì)三維空間向量$\mathbf{b}$,其長度為$L$,與$x$軸、$y$軸和$z$軸的夾角分別為$\alpha$、$\beta$和$\gamma$,則其坐標(biāo)表示為$\mathbf{b}=(L\cos\alpha, L\cos\beta, L\cos\gamma)^\text{T}$。
2.3 點(diǎn)的表示
剛才我們定義了坐標(biāo)系——坐標(biāo)原點(diǎn)和三個(gè)不共面的向量組成,并且三維空間中的任意向量都可以由這三個(gè)向量唯一表示,但我們沒有講點(diǎn)怎么由坐標(biāo)系來定義。設(shè)在三維笛卡爾坐標(biāo)系中,坐標(biāo)原點(diǎn)為$O$,三個(gè)基向量分別為$\mathbf{i}$,$\mathbf{j}$,$\mathbf{k}$,我們要求$P$點(diǎn)的坐標(biāo),那么
$$\vec{OP} = x_{1}\mathbf{i} + y_{1}\mathbf{j} + z_{1}\mathbf{k}$$
于是,點(diǎn)$P$可以表示為
$$P = x_{1}\mathbf{i} + y_{1}\mathbf{j} + z_{1}\mathbf{k} + \mathbf{O}$$
所以,要想表示一個(gè)三維的點(diǎn),可以用四維坐標(biāo)來表示,例如剛才的$P$可以表示為$P = (\begin{array}{cccc} x_1 & y_1 & z_1 & 1\end{array})$,這就是齊次坐標(biāo)。對(duì)頂點(diǎn)來說,齊次坐標(biāo)才是其真正的表示方式。向量可以表示為$\mathbf{v} = (\begin{array}{cccc} x_1 & y_1 & z_1 & 0\end{array})$。
3 線性變換與齊次坐標(biāo)
3.1 概述
代數(shù)中的線性變換的概念很抽象,涉及到向量空間、線性映射之類的概念,在這里不做過多解釋,如下想了解可以度娘或必應(yīng)。給一個(gè)通俗點(diǎn)的解釋,三維線性變換就是將點(diǎn)/向量的坐標(biāo)值做一個(gè)運(yùn)算,使其坐標(biāo)值發(fā)生改變,這在幾何中的反映就是幾何體的形狀被改變了。在計(jì)算機(jī)圖形學(xué)中,線性變換一般是指平移、旋轉(zhuǎn)、縮放、投影(正交投影和透視投影)以及這些基本變換的綜合運(yùn)算。通過剛才的描述,我們知道一下幾點(diǎn)信息:幾何中的點(diǎn)或向量由四個(gè)坐標(biāo)值確定,而坐標(biāo)值是由坐標(biāo)系確定的,坐標(biāo)系又是由三個(gè)不共面的向量和坐標(biāo)原點(diǎn)構(gòu)成。也就是說,對(duì)于同一點(diǎn),在不同的坐標(biāo)系下,描述它的坐標(biāo)值是不一樣的,而變換就是建立這兩種不同描述之間的聯(lián)系——所以在以前我們稱之為坐標(biāo)變換。例如:在坐標(biāo)系$\mathbf{O}_1-\mathbf{i}_1\mathbf{j}_1\mathbf{k}_1$坐標(biāo)系下,某一點(diǎn)可以描述為$P$點(diǎn)可以用四元祖$(x_1, y_1, z_1, o_1)$描述,
\begin{equation}\label{p2}P = \begin{array}{cccc} (x_1 & y_1 & z_1 & o_1)\end{array}\left(\begin{array}{c}\mathbf{i}_1 \\ \mathbf{j}_1 \\ \mathbf{k}_1 \\ \mathbf{O}_1\end{array}\right) = (\begin{array}{cccc} \mathbf{i}_1 & \mathbf{j}_1 & \mathbf{k}_1 & \mathbf{o_1}\end{array})\left(\begin{array}{c}x_1 \\ y_1 \\ z_1 \\ o_1 \end{array}\right)\end{equation}
在另一個(gè)坐標(biāo)系為$\mathbf{O}_2-\mathbf{i}_2\mathbf{j}_2\mathbf{k}_2$,可以用另一個(gè)有序元組描述它,設(shè)為$(x_2, y_2, z_2, o_2)$
\begin{equation}\label{p1}P = \begin{array}{cccc} (x_2 & y_2 & z_2 & o_2)\end{array}\left(\begin{array}{c}\mathbf{i}_2 \\ \mathbf{j}_2 \\ \mathbf{k}_2 \\ \mathbf{O}_2\end{array}\right) = (\begin{array}{cccc} \mathbf{i}_2 & \mathbf{j}_2 & \mathbf{k}_2 & \mathbf{O_2}\end{array})\left(\begin{array}{c}x_2 \\ y_2 \\ z_2 \\ o_2 \end{array}\right)\end{equation}
那么怎么建立$(\ref{p1})$和$(\ref{p2})$之間的聯(lián)系呢?還是之前我們說的,任意一個(gè)三維向量都可以表示用三個(gè)不共面的向量表示,所以$\mathbf{i}_2, \mathbf{j}_2,?\mathbf{k}_2$可以用$\mathbf{i}_1,?\mathbf{j}_1,?\mathbf{k}_1$線性表出:
$$\mathbf{i}_2 = T_{11} \mathbf{i}_1 + T_{21} \mathbf{j}_1 + T_{31} \mathbf{k}_1 + 0 \mathbf{O}_1$$
$$\mathbf{j}_2 = T_{12} \mathbf{i}_1 + T_{22} \mathbf{j}_1 + T_{32} \mathbf{k}_1 + 0 \mathbf{O}_1$$
$$\mathbf{k}_2 = T_{13} \mathbf{i}_1 + T_{23} \mathbf{j}_1 + T_{33} \mathbf{k}_1 + 0 \mathbf{O}_1$$
$$\mathbf{O}_2 = T_{14} \mathbf{i}_1 + T_{24} \mathbf{j}_1 + T_{34} \mathbf{k}_1 + T_{44} \mathbf{O}_1$$
?即:
$$(\begin{array}{cccc}\mathbf{i}_2 & \mathbf{j}_2 & \mathbf{k}_2 & \mathbf{O}_2 \end{array}) = (\begin{array}{cccc}\mathbf{i}_1 & \mathbf{j}_1 & \mathbf{k}_1 & \mathbf{O}_1 \end{array})\left(\begin{array}{cccc}T_{11} & T_{12} & T_{13} & T_{14} \\T_{21} & T_{22} & T_{23} & T_{24}\\T_{31} & T_{32} & T_{33} & T_{34}\\0 & 0 &0& T_{44}\end{array}\right)$$
于是,我們就可以寫出從$(\begin{array}{cccc}x_1 & y_1 & z_1 & o_1 \end{array})^{\text{T}}$變換到$(\begin{array}{cccc}x_2 & y_2 & z_2 & o_2 \end{array})^{\text{T}}$的變換表達(dá)式為:
$$\left(\begin{array}{c}x_2 \\ y_2 \\ z_2 \\ o_2 \end{array}\right) = (\begin{array}{cccc}\mathbf{i}_1 & \mathbf{j}_1 & \mathbf{k}_1 & \mathbf{O}_1 \end{array})\left(\begin{array}{cccc}T_{11} & T_{12} & T_{13} & T_{14} \\T_{21} & T_{22} & T_{23} & T_{24}\\T_{31} & T_{32} & T_{33} & T_{34}\\0.0 & 0.0 &0.0& T_{44}\end{array}\right)\left(\begin{array}{c}x_1 \\ y_1 \\ z_1 \\ o_1 \end{array}\right)?$$
其中,將
$$T=\left(\begin{array}{cccc}T_{11} & T_{12} & T_{13} & T_{14} \\T_{21} & T_{22} & T_{23} & T_{24}\\T_{31} & T_{32} & T_{33} & T_{34}\\0.0 & 0.0 &0.0& T_{44}\end{array}\right)$$
稱為坐標(biāo)變換矩陣。接下來主要就是講解怎么求基本的坐標(biāo)變換(仿射變換)矩陣。
3.2 縮放
縮放應(yīng)該是所有線性變換中最簡單的變換了。執(zhí)行縮放操作,例如將一個(gè)向量縮放為原來的$s$倍,相當(dāng)于原點(diǎn)不變,$x$、$y$、$z$三個(gè)坐標(biāo)軸縮放為原來的$s$倍。根據(jù)3.1介紹的,縮放操作的變換矩陣為:
$$T_s = \left(\begin{array}{cccc}s & 0 & 0 & 0 \\ 0 & s & 0 & 0 \\ 0 & 0 & s & 0 \\ 0 & 0 & 0 & 1\end{array}\right)$$
3.3 平移
所謂平移,就是在坐標(biāo)系中的三個(gè)坐標(biāo)軸保持不變,原點(diǎn)沿著平移向量移動(dòng)到新位置。假設(shè)平移向量為$v_p = (\begin{array}{cccc}x_p & y_p & z_p & 0 \end{array})$同樣,根據(jù)可以得到,平移操作的變換矩陣為:
$$T_p = \left(\begin{array}{cccc}1 & 0 & 0 & x_p \\ 0 & 1 & 0 & y_p \\ 0 & 0 & 1 & z_p \\ 0 & 0 & 0 & 1\end{array}\right)$$
3.4 旋轉(zhuǎn)
最后來推導(dǎo)最難的旋轉(zhuǎn)變換矩陣。與平移、旋轉(zhuǎn)矩陣的不同,旋轉(zhuǎn)矩陣就不那么直觀了。下面,我們來具體看一下旋轉(zhuǎn)矩陣的推導(dǎo),這個(gè)推導(dǎo)是執(zhí)行三次向量的平行四邊形法則進(jìn)行分解得到,整個(gè)分解過程如下圖所示:
三次分解由不同的顏色表示出來了,分別是紅色、淺藍(lán)色和紫色。
已知條件:$\mathbf{i}$、$\mathbf{j}$和$\mathbf{k}$是三維笛卡爾坐標(biāo)系的基向量,原點(diǎn)為$O$,旋轉(zhuǎn)軸為$\mathbf{u}$,也是單位向量,向量$\mathbf{i'}$為$x$方向的基向量$\mathbf{i}$繞旋轉(zhuǎn)軸$\mathbf{u}$旋轉(zhuǎn)$\theta$后的新向量——旋轉(zhuǎn)后坐標(biāo)系$x$軸的基向量。
我們的目的:將向量$\mathbf{i'}$用基向量$\mathbf{i}$、$\mathbf{j}$和$\mathbf{k}$表示出來。
第一步向量分解:將$\mathbf{i'}$分解為沿著旋轉(zhuǎn)軸$\mathbf{u}$的向量$\vec{OA}$和垂直于$\mathbf{u}$的向量$\vec{OB}$,則:
\begin{equation}\label{341}\mathbf{i'} = \vec{OA} + \vec{OB}\end{equation}
且:
\begin{equation}\label{342}\vec{OA} = u_x \mathbf{u} = u_x^2\mathbf{i} + u_xu_y\mathbf{j} + u_xu_z\mathbf{k}\end{equation}
第二步向量分解:將$\mathbf{i}$分解為沿著旋轉(zhuǎn)軸$\mathbf{u}$的向量$\vec{OA}$和垂直于$\mathbf{u}$的向量$\vec{OC}$,則
$$\mathbf{i} = \vec{OA} + \vec{OC}$$
且:
\begin{equation}\label{344}\vec{OC} = \mathbf{i} - u_x\mathbf{u} = (1-u_x^2)\mathbf{i} - u_xu_y\mathbf{j} - u_xu_z\mathbf{k} \end{equation}
第三步向量分解:建立$\vec{OB}$與$\vec{OC}$之間的聯(lián)系,將向量$\vec{OB}$分解為沿著$\vec{OC}$方向的向量$\vec{OD}$和垂直于$\vec{OB}$的向量$\vec{OE}$,則
\begin{equation}\label{345}\vec{OB} = \vec{OD} + \vec{OE}\end{equation}
根據(jù)$\ref{344}$可得:
\begin{equation}\label{346}\vec{OD} = |\vec{OB}|\cos\theta\frac{\vec{OC}}{|\vec{OC}|} = \cos\theta?\vec{OC} = \cos\theta(\mathbf{i} - u_x\mathbf{u}) = (1-u_x^2)\cos\theta \mathbf{i} - u_xu_y\cos\theta \mathbf{j} -u_xu_z\cos\theta \mathbf{k} \end{equation}
另外,注意到$\vec{OE}$和$\vec{OC}$垂直,$\mathbf{u}$是旋轉(zhuǎn)軸,則$\mathbf{u}$與平面$OEBD$垂直,所以$\mathbf{u}$與$OE$垂直,則$\vec{OE}$在向量$\mathbf{u}$和向量$\vec{OC}$的叉乘向量上,假設(shè) $\vec{OF} = \mathbf{u}?\times?\vec{OC}$,于是:
$$\vec{OE} = k\vec{OF} = k\mathbf{u}\times \vec{OC}=k\mathbf{u}\times (\mathbf{i} - u_x\mathbf{u}) = k \mathbf{u}\times \mathbf{i}$$
所以現(xiàn)在求出$k$就可以了,由叉乘定義:$|\vec{OF}| = |\mathbf{u}||\vec{OC}|sin(90) = |\vec{OC}| = |\vec{OB}|$,所以:$k=\sin\theta$,最后得到
\begin{equation}\label{349}\vec{OE}=\sin\theta \mathbf{u}\times (\mathbf{i} - u_x\mathbf{u}) = \sin\theta \left(\begin{array} \mathbf{i} & \mathbf{j} & \mathbf{k} \\ u_x & u_y & u_z \\ 1 & 0 & 0 \end{array}\right) = ?u_z\sin\theta\mathbf{j} -u_y\sin\theta\mathbf{k}\end{equation}
將$(\ref{346})$和$(\ref{349})$代入$(\ref{345})$得:
\begin{equation}\label{3410}\vec{OB} = (1-u_x^2)\cos\theta\mathbf{i} - (u_xu_y\cos\theta - u_z\sin\theta)\mathbf{j} - (u_xu_z\cos\theta + u_y\sin\theta)\mathbf{k} \end{equation}
最后,將$(\ref{342})$和$(\ref{3410})$代入$(\ref{341})$可得
$$\mathbf{i'} = (\cos\theta + u_x^2(1-\cos\theta))\mathbf{i} + (u_xu_y(1-cos\theta) + u_z\sin\theta)\mathbf{j} + (u_xu_z(1-\cos\theta) - u_y\sin\theta)\mathbf{k} + 0\mathbf{O}$$
其余兩個(gè)變換后的基向量$\mathbf{i'}$和$\mathbf{j'}$也可以由$\mathbf{i}$、$\mathbf{j}$和$\mathbf{k}$表示出來,最終得到齊次旋轉(zhuǎn)矩陣為
$$M_r = \left(\begin{array}{cccc}\cos\theta+u_x^2(1-\cos\theta)& u_xu_y(1-\cos\theta)-u_z\sin\theta & u_xu_z(1-\cos\theta+u_y\sin\theta & 0 \\ u_yu_x(1-\cos\theta)+u_z\sin\theta & \cos\theta+u_y^2(1-\cos\theta)?& u_yu_z(1-\cos\theta)-u_x\sin\theta & 0 \\ u_zu_x(1-\cos\theta)-u_y\sin\theta & u_zu_y(1-\cos\theta)+u_x\sin\theta & \cos\theta+u_z^2(1-\cos\theta) & 0 \\ 0 & 0 & 0 & 1\end{array}\right)$$
4 總結(jié)
最后總結(jié)一下,在這篇博文中我們講述了點(diǎn)及其相對(duì)性,接著介紹了向量的概念,由平行四邊形法則引出坐標(biāo)系的概念,然后介紹了點(diǎn)在坐標(biāo)系下的表示,最后介紹了坐標(biāo)變換和變換矩陣的概念,給出了三種基本變換——平移變換、旋轉(zhuǎn)變換和縮放變換的變換矩陣。這些矩陣綜合運(yùn)用,就構(gòu)成了三維空間中復(fù)雜的變換了,三維變換是三維圖形繪制的基礎(chǔ),也是學(xué)習(xí)OpenGL時(shí)較難理解的知識(shí)點(diǎn)之一。
轉(zhuǎn)載于:https://www.cnblogs.com/lijihong/p/5396819.html
總結(jié)
以上是生活随笔為你收集整理的OpenGL学习之路(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 调DHT22
- 下一篇: install kinect drive