首先,來繪制一個多邊形
- 在 [demo1].來一個最簡單的三角形吧 的demo的基礎(chǔ)上轿偎,將vTops里的頂點改成5個(或者6個7個8個...),并將全局容器內(nèi)的繪制方式改為GL_POLYGON(或者改成其他的方式典鸡,見下圖),并修改頂點個數(shù)
GLfloat vTops[] = {
-0.4, -0.3, 0, //v0
0.1, -0.7, 0, //v1
0.6, -0.1, 0, //v2
0.4, 0.5, 0, //v3
-0.2, 0.4, 0 // v4
};
/**
* GL_TRIANGLES 三角形
*/
triangleBatch.Begin(GL_POLYGON, 5);
從上圖可以看到有很多種繪圖方式坏晦,可以根據(jù)需要選擇自己需要的方式萝玷,這里是5個頂點,所以選擇了GL_POLYGON(8個也可以選擇POLYGON昆婿,會按照順序依次連接并繪制封閉圖形)球碉。
-
直接運行,就可以看到一個5變形成功的繪制在窗口內(nèi)了 ??????
接下來仓蛆,讓多邊形動起來
-
設(shè)置一個全局變量睁冬,用于存放v0, v1, v2, v3, v4相對于v0的位置
同時設(shè)置一個全局變量,用于存放v0,v1,v2,v3,v4的初始位置和新位置
//v0, v1, v2, v3, v4 相對于v0的相對位置 GLfloat relate_tops[15] = { }; //v0, v1, v2, v3, v4 的新位置 GLfloat movie_tops[15] = { };
-
在準(zhǔn)備時計算相對位置
for (int i = 0 ; i < 15; i++) { movie_tops[i] = vTops[i]; relate_tops[i] = vTops[i] - vTops[i % 3]; printf("%.01f - %0.1f\n", movie_tops[i], relate_tops[i]); }
這里是5個點看疙,所以要循環(huán)3*5=15次豆拨,如果是n個點,則需要循環(huán) 3 *n次
-
注冊一個新的函數(shù)能庆,用于捕獲鍵盤的輸入
/** * @param key 鍵盤輸入的鍵 */ void SpecialKeys(int key, int x, int y) { } glutSpecialFunc(SpecialKeys);
-
設(shè)置步長stepSize施禾,用作每次移動時的移動距離,以此來控制移動速度
GLfloat stepSize = 0.01;
這里設(shè)置為0.01搁胆,每次會移動屏幕0.5%的距離(屏幕總長度為 1 - (-1) = 2)
-
確定一個參考點弥搞,根據(jù)參考點與其他點的相對位置關(guān)系,得到其他點的位置
GLfloat blockX = movie_tops[0]; GLfloat blockY = movie_tops[1];
這里將v0作為參考點渠旁,所有點會隨著v0的移動而移動攀例,之前設(shè)置相對點的時候也是以v0作為參考點的
-
檢測鍵盤的輸入,確認(rèn)參考點的移動位置,向上移動顾腊,y增大肛度,向下移動,y減小投慈,向左移動承耿,x減小,向右移動伪煤,x增大
//向上移動 switch (key) { //方向鍵 上 case GLUT_KEY_UP: blockY = blockY + stepSize; break; //方向鍵 下 case GLUT_KEY_DOWN: blockY = blockY - stepSize; break; //方向鍵 左 case GLUT_KEY_LEFT: blockX = blockX - stepSize; break; //方向鍵 右 case GLUT_KEY_RIGHT: blockX = blockX + stepSize; break; //鍵盤 i 上 case 105: blockY = blockY + stepSize; break; //鍵盤 k 下 case 107: blockY = blockY - stepSize; break; //鍵盤 < 下 case 44: blockY = blockY - stepSize; break; //鍵盤 j 左 case 106: blockX = blockX - stepSize; break; //鍵盤 l 右 case 108: blockX = blockX + stepSize; break; //鍵盤 u 左上 case 117: blockX = blockX - stepSize; blockY = blockY + stepSize; break; //鍵盤 o 右上 case 111: blockX = blockX + stepSize; blockY = blockY + stepSize; break; //鍵盤 m 左下 case 109: blockX = blockX - stepSize; blockY = blockY - stepSize; break; //鍵盤 > 右下 case 46: blockX = blockX + stepSize; blockY = blockY - stepSize; break; default: printf("Unwork Key %d\n", key); break; }
在這里加袋,我額外根據(jù)按鍵時打印的信號另外增加了9個鍵,遺憾的是抱既,E和D不知為何無法響應(yīng)(就是按了沒反應(yīng))职烧,所以并沒用WSAD
-
再根據(jù)相對位置,將移動后的點和v0的關(guān)系求出
for (int i = 0 ; i < 15; i++) { if (i % 3 == 0) { movie_tops[i] = relate_tops[i] + blockX; } else if (i % 3 == 1) { movie_tops[i] = relate_tops[i] + blockY; } else { movie_tops[i] = 0; } // printf("%.01f", movie_tops[i]); }
-
在將移動后新的位置復(fù)制進(jìn)容器內(nèi)防泵,提交渲染
這個時候已經(jīng)有了一支畫筆蚀之,所以只需要強(qiáng)制重新渲染就OK
triangleBatch.CopyVertexData3f(movie_tops); glutPostRedisplay();
-
運行一下,5邊形顯示正常捷泞,按一下鍵盤足删,都正常,太棒了~
但是锁右!但是失受!奇怪的事情發(fā)生了,我再按E和D鍵咏瑟,他們的功能和I和J的一模一樣拂到,E向上移動,D向左移動码泞,真的神奇 =兄旬。=(有小伙伴知道嗎?求解答)
-
到這里余寥,可移動的多邊形就搞定了领铐,但是并不完善,還有邊界的檢測沒做劈狐。
為了做邊界檢測罐孝,我們需要設(shè)置一組臨時數(shù)據(jù),如果臨時數(shù)據(jù)超出邊界肥缔,就讓這一次的移動無效
GLfloat tem_point[15] = { }; for (int i = 0 ; i < 15; i++) { if (i % 3 == 0) { tem_point[i] = relate_tops[i] + blockX; } else if (i % 3 == 1) { tem_point[i] = relate_tops[i] + blockY; } else { tem_point[i] = 0; } if (tem_point[i] > 1 || tem_point[i] < -1) { return; } }
經(jīng)測試莲兢,完美~?? (也可以考慮將tem_point設(shè)置為全局變量)
但是,當(dāng)點特別多的時候续膳,循環(huán)上千次改艇,上萬次的時候,這種方式未免有些無用(一個精細(xì)的2d模型上萬的點正常吧)坟岔,該怎么辦呢谒兄?這時候就要用上線性代數(shù)了。具體怎么用社付?看下一篇
~