[demo2].進(jìn)階啦击困,來一個可以移動的多邊形吧

跳去目錄


首先,來繪制一個多邊形

  1. [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);
image-20200705012351940.png

從上圖可以看到有很多種繪圖方式坏晦,可以根據(jù)需要選擇自己需要的方式萝玷,這里是5個頂點,所以選擇了GL_POLYGON(8個也可以選擇POLYGON昆婿,會按照順序依次連接并繪制封閉圖形)球碉。

  1. 直接運行,就可以看到一個5變形成功的繪制在窗口內(nèi)了 ??????

    image-20200705013621924.png

接下來仓蛆,讓多邊形動起來

  1. 設(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] = { };
    
  1. 在準(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次

  2. 注冊一個新的函數(shù)能庆,用于捕獲鍵盤的輸入

    /**
     * @param key 鍵盤輸入的鍵
     */
    void SpecialKeys(int key, int x, int y) {
        
    }
    
    glutSpecialFunc(SpecialKeys);
    
  3. 設(shè)置步長stepSize施禾,用作每次移動時的移動距離,以此來控制移動速度

    GLfloat stepSize = 0.01;
    

    這里設(shè)置為0.01搁胆,每次會移動屏幕0.5%的距離(屏幕總長度為 1 - (-1) = 2)

  4. 確定一個參考點弥搞,根據(jù)參考點與其他點的相對位置關(guān)系,得到其他點的位置

    GLfloat blockX = movie_tops[0];
    GLfloat blockY = movie_tops[1];
    

    這里將v0作為參考點渠旁,所有點會隨著v0的移動而移動攀例,之前設(shè)置相對點的時候也是以v0作為參考點的

  5. 檢測鍵盤的輸入,確認(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

  6. 再根據(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]);
      }
    
  7. 在將移動后新的位置復(fù)制進(jìn)容器內(nèi)防泵,提交渲染

    這個時候已經(jīng)有了一支畫筆蚀之,所以只需要強(qiáng)制重新渲染就OK

    triangleBatch.CopyVertexData3f(movie_tops);
    glutPostRedisplay();
    
  8. 運行一下,5邊形顯示正常捷泞,按一下鍵盤足删,都正常,太棒了~

    但是锁右!但是失受!奇怪的事情發(fā)生了,我再按E和D鍵咏瑟,他們的功能和I和J的一模一樣拂到,E向上移動,D向左移動码泞,真的神奇 =兄旬。=(有小伙伴知道嗎?求解答)

  9. 到這里余寥,可移動的多邊形就搞定了领铐,但是并不完善,還有邊界的檢測沒做劈狐。

    為了做邊界檢測罐孝,我們需要設(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è)置為全局變量)

    點我下載這個demo


但是,當(dāng)點特別多的時候续膳,循環(huán)上千次改艇,上萬次的時候,這種方式未免有些無用(一個精細(xì)的2d模型上萬的點正常吧)坟岔,該怎么辦呢谒兄?這時候就要用上線性代數(shù)了。具體怎么用社付?看下一篇


跳去目錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末承疲,一起剝皮案震驚了整個濱河市邻耕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌燕鸽,老刑警劉巖兄世,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異啊研,居然都是意外死亡御滩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門党远,熙熙樓的掌柜王于貴愁眉苦臉地迎上來削解,“玉大人,你說我怎么就攤上這事沟娱》胀裕” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵花沉,是天一觀的道長柳爽。 經(jīng)常有香客問我,道長碱屁,這世上最難降的妖魔是什么磷脯? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮娩脾,結(jié)果婚禮上赵誓,老公的妹妹穿的比我還像新娘。我一直安慰自己柿赊,他們只是感情好俩功,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著碰声,像睡著了一般诡蜓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胰挑,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天蔓罚,我揣著相機(jī)與錄音,去河邊找鬼瞻颂。 笑死豺谈,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贡这。 我是一名探鬼主播茬末,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盖矫!你這毒婦竟也來了丽惭?” 一聲冷哼從身側(cè)響起击奶,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吐根,沒想到半個月后正歼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡拷橘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了喜爷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冗疮。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖檩帐,靈堂內(nèi)的尸體忽然破棺而出术幔,到底是詐尸還是另有隱情,我是刑警寧澤湃密,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布诅挑,位于F島的核電站,受9級特大地震影響泛源,放射性物質(zhì)發(fā)生泄漏拔妥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一达箍、第九天 我趴在偏房一處隱蔽的房頂上張望没龙。 院中可真熱鬧,春花似錦缎玫、人聲如沸硬纤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽筝家。三九已至,卻和暖如春邻辉,著一層夾襖步出監(jiān)牢的瞬間溪王,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工恩沛, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留在扰,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓雷客,卻偏偏與公主長得像芒珠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子搅裙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348