案例一:繪制正方形并通過鍵位控制

繪制正方形聪轿,以改變頂點坐標的方式鍵位控制上下左右平移--->通過重新計算頂點坐標,來達到移動效果

這里主要分為兩步實現(xiàn):

  • 繪制正方形
  • 特殊鍵位移動函數(shù)

繪制正方形

之前我們做過三角形的繪制笛质,這里正方形的繪制只需要改變頂點坐標,然后修改setupRC函數(shù)中圖元的連接方式GL_TRIANGLES修改為 GL_TRIANGLE_FAN ,4就行了捞蚂。

//blockSize 邊長
GLfloat blockSize = 0.3f;
//正方形四個點的坐標
GLfloat vVerts[] = {
    -blockSize, -blockSize, 0.0f,
    blockSize, -blockSize, 0.0f,
    blockSize, blockSize, 0.0f,
    -blockSize, blockSize, 0.0f,
};

鍵位控制效果

主要是指正方形根據(jù)選擇鍵盤的上下左右鍵移動妇押。

該效果的實現(xiàn)有兩種方式

  • 坐標更新方式
  • 矩陣方式

打個比方,有100件需要染同一種顏色的衣服姓迅,你可以選擇一件一件的染色敲霍,也可以選擇同時將100件放入染缸,一起染色丁存,

其中一件一件染色指代的就是坐標更新方式肩杈,適用于頂點較少的圖形,
同時放入染色指代的就是矩陣方式解寝,當圖形頂點非常多的扩然,再用坐標更新就不合適了,需要使用矩陣來同時更新聋伦。

坐標更新方式

頂點根據(jù)相對頂點逐個更新頂點坐標与学,在SpecialKeys函數(shù)中完成鍵位移動時坐標的更新,并手動調(diào)用渲染嘉抓。

三個自定義函數(shù)的流程圖如下:

坐標更新方式

主要函數(shù)代碼

changeSize

/*
 在窗口大小改變時索守,接收新的寬度&高度。
 */
void changeSize(int w,int h)
{
    /*
      x,y 參數(shù)代表窗口中視圖的左下角坐標抑片,而寬度卵佛、高度是像素為表示,通常x,y 都是為0
     */
    glViewport(0, 0, w, h);
    
}

RenderScene

void RenderScene(void)
{

    //1.清除一個或者一組特定的緩存區(qū)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    
    //2.設置一組浮點數(shù)來表示紅色
    GLfloat vRed[] = {1.0,0.0,0.0,1.0f};
    
    //頂點數(shù)據(jù)傳遞到存儲著色器
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
    
    //提交著色器
    triangleBatch.Draw();

    //將后臺緩沖區(qū)進行渲染敞斋,然后結(jié)束后交換給前臺
    glutSwapBuffers();
    
}

setupRC

void setupRC()
{
    //設置清屏顏色(背景顏色)
    glClearColor(0.98f, 0.40f, 0.7f, 1);
    
    //初始化一個渲染管理器截汪。
    shaderManager.InitializeStockShaders();

  //指定頂點
    //修改為GL_TRIANGLE_FAN ,4個頂點
    triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
    
}

SpecialKeys

void SpecialKeys(int key, int x, int y){
    
    GLfloat stepSize = 0.025f;
    
    GLfloat blockX = vVerts[0];
    GLfloat blockY = vVerts[10];

    
    
    if (key == GLUT_KEY_UP) {
        
        blockY += stepSize;
    }
    
    if (key == GLUT_KEY_DOWN) {
        
        blockY -= stepSize;
    }
    
    if (key == GLUT_KEY_LEFT) {
        blockX -= stepSize;
    }
    
    if (key == GLUT_KEY_RIGHT) {
        blockX += stepSize;
    }

    //觸碰到邊界(4個邊界)的處理
    
    //當正方形移動超過最左邊的時候
    if (blockX < -1.0f) {
        blockX = -1.0f;
    }
    
    //當正方形移動到最右邊時
    //1.0 - blockSize * 2 = 總邊長 - 正方形的邊長 = 最左邊點的位置
    if (blockX > (1.0 - blockSize * 2)) {
        blockX = 1.0f - blockSize * 2;
    }
    
    //當正方形移動到最下面時
    //-1.0 - blockSize * 2 = Y(負軸邊界) - 正方形邊長 = 最下面點的位置
    if (blockY < -1.0f + blockSize * 2 ) {
        
        blockY = -1.0f + blockSize * 2;
    }
    
    //當正方形移動到最上面時
    if (blockY > 1.0f) {
        
        blockY = 1.0f;
        
    }

    
    // Recalculate vertex positions
    vVerts[0] = blockX;
    vVerts[1] = blockY - blockSize*2;
    
    vVerts[3] = blockX + blockSize*2;
    vVerts[4] = blockY - blockSize*2;
    
    vVerts[6] = blockX + blockSize*2;
    vVerts[7] = blockY;
    
    vVerts[9] = blockX;
    vVerts[10] = blockY;
    
    triangleBatch.CopyVertexData3f(vVerts);
    
    glutPostRedisplay();
}

矩陣方式

主要是根據(jù)x軸植捎、y軸移動的距離衙解,生成一個平移矩陣,通過圖形*平移矩陣 = 移動后的圖形焰枢,得到最終效果

涉及兩個函數(shù):RenderScene蚓峦、SpecialKeys

矩陣方式中自定義函數(shù)的流程如下:

矩陣方式

SpecialKeys 函數(shù)

  • 定義步長及兩個全局變量(相對于x軸和y軸的平移距離)
//記錄移動圖形時,在x軸上平移的距離
GLfloat xPos = 0.0f;
//記錄移動圖形時济锄,在y軸上平移的距離
GLfloat yPos = 0.0f;

GLfloat stepSize = 0.025f;

  • 根據(jù)移動方向暑椰,計算移動距離
  • 邊緣碰撞處理
  • 手動觸發(fā)重新渲染

具體實現(xiàn)如下:

//使用矩陣方式(一起搞定),不需要修改每個頂點荐绝,只需要記錄移動步長一汽,碰撞檢測
void SpecialKeys(int key, int x, int y){

    GLfloat stepSize = 0.025f;

    if (key == GLUT_KEY_UP) {

        yPos += stepSize;
    }

    if (key == GLUT_KEY_DOWN) {
        yPos -= stepSize;
    }

    if (key == GLUT_KEY_LEFT) {
        xPos -= stepSize;
    }

    if (key == GLUT_KEY_RIGHT) {
        xPos += stepSize;
    }

    //碰撞檢測 xPos是平移距離,即移動量
    if (xPos < (-1.0f + blockSize)) {

        xPos = -1.0f + blockSize;
    }

    if (xPos > (1.0f - blockSize)) {
        xPos = 1.0f - blockSize;
    }

    if (yPos < (-1.0f + blockSize)) {
        yPos = -1.0f + blockSize;
    }

    if (yPos > (1.0f - blockSize)) {
        yPos = 1.0f - blockSize;
    }

    glutPostRedisplay();

}

RenderScene 函數(shù)
主要步驟如下:

  • 清理特定緩存區(qū)
  • 根據(jù)平移距離計算平移矩陣
  • 將矩陣結(jié)果交給存儲著色器(平面著色器)中繪制
    在位置更新方式中低滩,使用的是單元著色器召夹,而矩陣方式中岩喷,涉及的矩陣是4*4的,單元著色器不夠用监憎,所以使用平面著色器

具體的代碼實現(xiàn)如下

//開始渲染
void RenderScene(void)

{
    //1.清除一個或者一組特定的緩存區(qū)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    //1.設置顏色RGBA
    GLfloat vRed[] = {1.0f, 0.5f, 0.0f, 1.0f};

    //定義矩陣
    M3DMatrix44f mTransformMatrix;

    //平移矩陣
    m3dTranslationMatrix44(mTransformMatrix, xPos, yPos, 0.0f);

    //當單元著色器不夠用時均驶,使用平面著色器
    //參數(shù)1:存儲著色器類型
    //參數(shù)2:使用什么矩陣變換
    //參數(shù)3:顏色
    shaderManager.UseStockShader(GLT_SHADER_FLAT, mTransformMatrix, vRed);

    //提交著色器
    triangleBatch.Draw();
    glutSwapBuffers();
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市枫虏,隨后出現(xiàn)的幾起案子妇穴,更是在濱河造成了極大的恐慌,老刑警劉巖隶债,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腾它,死亡現(xiàn)場離奇詭異,居然都是意外死亡死讹,警方通過查閱死者的電腦和手機瞒滴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赞警,“玉大人妓忍,你說我怎么就攤上這事±⒌” “怎么了世剖?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長笤虫。 經(jīng)常有香客問我旁瘫,道長,這世上最難降的妖魔是什么琼蚯? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任酬凳,我火速辦了婚禮,結(jié)果婚禮上遭庶,老公的妹妹穿的比我還像新娘宁仔。我一直安慰自己,他們只是感情好峦睡,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布翎苫。 她就那樣靜靜地躺著,像睡著了一般赐俗。 火紅的嫁衣襯著肌膚如雪拉队。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天阻逮,我揣著相機與錄音,去河邊找鬼秩彤。 笑死叔扼,一個胖子當著我的面吹牛事哭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瓜富,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼鳍咱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了与柑?” 一聲冷哼從身側(cè)響起谤辜,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎价捧,沒想到半個月后丑念,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡结蟋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年脯倚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嵌屎。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡推正,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宝惰,到底是詐尸還是另有隱情植榕,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布尼夺,位于F島的核電站内贮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏汞斧。R本人自食惡果不足惜夜郁,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粘勒。 院中可真熱鬧竞端,春花似錦、人聲如沸庙睡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乘陪。三九已至统台,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啡邑,已是汗流浹背贱勃。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贵扰。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓仇穗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親戚绕。 傳聞我的和親對象是個殘疾皇子婿屹,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容