Qt OpenGL 3D模型
這次教程中,我們將之前幾課的基礎上,教大家如何建立立體的3D模型。我們將開始生成真正的3D物件,而不是像之前那幾課那樣3D世界中的2D物件。我們會把之前的三角形變為立體的金字塔模型,把四邊形變為立方體。
我們給三角形增加左側面、右側面、後側面來生成一個金字塔。給正方形增加左、右、上、下及背面生成一個立方體。我們混合金字塔上的顏色,建立一個平滑著色的物件;給立方體的每一面來個不同的顏色。
程式執行時效果如下:
下面進入教程:
要實現3D模型,只需在第04課程式碼的基礎上,對paintGL()函式作一定的修改。
下面我將重寫整個paintGL()函式,具體程式碼如下:
1 void MyGLWidget::paintGL() // 從這裡開始進行所以的繪製
2 {
3 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除螢幕和深度快取
4 glLoadIdentity(); //重置當前的模型觀察矩陣
5
6 glTranslatef(-1.5f, 0.0f, -6.0f); //左移1.5單位,並移入螢幕6.0單位
7 glRotatef(m_rtri, 0.0f, 1.0f, 0.0f); //繞y軸旋轉三角形
8 glBegin(GL_TRIANGLES); //開始繪製金字塔
9 glColor3f(1.0f, 0.0f, 0.0f); //紅色
10 glVertex3f(0.0f, 1.0f, 0.0f); //上頂點(前側面)
11 glColor3f(0.0f, 1.0f, 0.0f); //綠色
12 glVertex3f(-1.0f, -1.0f, 1.0f); //左下(前側面)
13 glColor3f(0.0f, 0.0f, 1.0f); //藍色
14 glVertex3f(1.0f, -1.0f, 1.0f); //右下(前側面)
15
16 glColor3f(1.0f, 0.0f, 0.0f); //紅色
17 glVertex3f(0.0f, 1.0f, 0.0f); //上頂點(右側面)
18 glColor3f(0.0f, 0.0f, 1.0f); //藍色
19 glVertex3f(1.0f, -1.0f, 1.0f); //左下(右側面)
20 glColor3f(0.0f, 1.0f, 0.0f); //綠色
21 glVertex3f(1.0f, -1.0f, -1.0f); //右下(右側面)
22
23 glColor3f(1.0f, 0.0f, 0.0f); //紅色
24 glVertex3f(0.0f, 1.0f, 0.0f); //上頂點(後側面)
25 glColor3f(0.0f, 1.0f, 0.0f); //綠色
26 glVertex3f(1.0f, -1.0f, -1.0f); //左下(後側面)
27 glColor3f(0.0f, 0.0f, 1.0f); //藍色
28 glVertex3f(-1.0f, -1.0f, -1.0f); //右下(後側面)
29
30 glColor3f(1.0f, 0.0f, 0.0f); //紅色
31 glVertex3f(0.0f, 1.0f, 0.0f); //上頂點(左側面)
32 glColor3f(0.0f, 0.0f, 1.0f); //藍色
33 glVertex3f(-1.0f, -1.0f, -1.0f); //左下(左側面)
34 glColor3f(0.0f, 1.0f, 0.0f); //綠色
35 glVertex3f(-1.0f, -1.0f, 1.0f); //右下(左側面)
36 glEnd(); //金字塔繪製結束
37
38 glLoadIdentity(); //重置模型觀察矩陣
39 glTranslatef(1.5f, 0.0f, -6.0f); //右移1.5單位,並移入螢幕6.0單位
40 glRotatef(m_rquad, 1.0f, 0.0f, 0.0f); //繞x軸旋轉四邊形
41 glBegin(GL_QUADS); //開始繪製立方體
42 glColor3f(0.0f, 1.0f, 0.0f); //綠色
43 glVertex3f(1.0f, 1.0f, -1.0f); //右上(頂面)
44 glVertex3f(-1.0f, 1.0f, -1.0f); //左上(頂面)
45 glVertex3f(-1.0f, 1.0f, 1.0f); //左下(頂面)
46 glVertex3f(1.0f, 1.0f, 1.0f); //右下(頂面)
47
48 glColor3f(1.0f, 0.5f, 0.0f); //橙色
49 glVertex3f(1.0f, -1.0f, 1.0f); //右上(底面)
50 glVertex3f(-1.0f, -1.0f, 1.0f); //左上(底面)
51 glVertex3f(-1.0f, -1.0f, -1.0f); //左下(底面)
52 glVertex3f(1.0f, -1.0f, -1.0f); //右下(底面)
53
54 glColor3f(1.0f, 0.0f, 0.0f); //紅色
55 glVertex3f(1.0f, 1.0f, 1.0f); //右上(前面)
56 glVertex3f(-1.0f, 1.0f, 1.0f); //左上(前面)
57 glVertex3f(-1.0f, -1.0f, 1.0f); //左下(前面)
58 glVertex3f(1.0f, -1.0f, 1.0f); //右下(前面)
59
60 glColor3f(1.0f, 1.0f, 0.0f); //黃色
61 glVertex3f(1.0f, -1.0f, -1.0f); //右上(後面)
62 glVertex3f(-1.0f, -1.0f, -1.0f); //左上(後面)
63 glVertex3f(-1.0f, 1.0f, -1.0f); //左下(後面)
64 glVertex3f(1.0f, 1.0f, -1.0f); //右下(後面)
65
66 glColor3f(0.0f, 0.0f, 1.0f); //藍色
67 glVertex3f(-1.0f, 1.0f, 1.0f); //右上(左面)
68 glVertex3f(-1.0f, 1.0f, -1.0f); //左上(左面)
69 glVertex3f(-1.0f, -1.0f, -1.0f); //左下(左面)
70 glVertex3f(-1.0f, -1.0f, 1.0f); //右下(左面)
71
72 glColor3f(1.0f, 0.0f, 1.0f); //紫色
73 glVertex3f(1.0f, 1.0f, -1.0f); //右上(右面)
74 glVertex3f(1.0f, 1.0f, 1.0f); //左上(右面)
75 glVertex3f(1.0f, -1.0f, 1.0f); //左下(右面)
76 glVertex3f(1.0f, -1.0f, -1.0f); //右下(右面)
77 glEnd(); //立方體繪製結束
78
79 m_rtri += 0.5f; //增加金字型的旋轉變數
80 m_rquad -= 0.5f; //減少立方體的旋轉變數
81 }
首先建立一個繞著其中心軸旋轉的金字塔,金字塔的上頂點高出原點一個單位,底面中心低於原點一個單位,上頂點在底面的投影位於底面的中心。要注意的是所有的面-三角形都是逆時針次序繪製的,這點十分重要,在以後的課程中我會做出解釋。現在,我們只需明白要麼都逆時針,要麼都順時針,但永遠不要將兩種次序混在一起,除非我們有足夠的理由必須這麼做。
開始繪製金字塔,應注意到四個側面處於同一glBegin(GL_TRIANGLES)和glEnd()語句之間,由於我們是用過三角形來構造這個金字塔的,OpenGL知道每三個點構成一個三角形,當它畫完一個三角形之後,如果還有餘下的點出現,它就以為新的三角形要開始繪製了。OpenGL在這裡並不會將四個點畫成一個四邊形,而是假定新的三角形開始了,千萬不要無意中增加任何多餘的點。對於顏色的選擇,我們只需對應好位置,就能取得不錯的效果。
開始繪製立方體,它由六個四邊形組成,所有的四邊形都以逆時針次序繪製,即按照右上、左上、左下、右下的次序繪畫。你也許認為畫立方體的背面的時候這個次序看起來好像順時針,但別忘了我們從立方體背後看背面的時候,與你現在所想的正好相反(我們是從立方體外面來觀察立方體的)。當然,你也可以嘗試用平滑著色來繪製立方體。
現在就可以執行程式檢視效果了!