OpenGL學(xué)習(xí)筆記4 (繪制一個可以動的正方形)

1.導(dǎo)入頭文件

#include "GLTools.h"
#include <GLUT/GLUT.h>

2.初始化要用到的全局變量

//初始化一個批次容器
GLBatch triangleBatch;
//初始化一個著色管理器
GLShaderManager shaderManager;

//所繪制的正方形的邊長宾濒。
GLfloat lengthOfSide = 0.2;

//正方形的頂點數(shù)組
GLfloat vVerts[] = {
   -(lengthOfSide/2), -(lengthOfSide/2), 0.0f, //A點
    (lengthOfSide/2), -(lengthOfSide/2), 0.0f, //B點
    (lengthOfSide/2), (lengthOfSide/2), 0.0f, //C點
    -(lengthOfSide/2), (lengthOfSide/2), 0.0f  //D點
};

3.在Main函數(shù)進行初始化窗口以及注冊回調(diào)函數(shù)

int main(int argc,char* argv[]) {
    //初始化GLUT庫抠刺,這個函數(shù)只是傳入命令參數(shù)并且初始化glut庫
    glutInit(&argc, argv);
    
    //初始化雙緩沖窗口
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    
    //GLUT窗口大小,窗口標(biāo)題
    glutInitWindowSize(600, 600);
    
    //創(chuàng)建一個標(biāo)題為Triangle的窗口
    glutCreateWindow("Triangle");
  
    //注冊重塑函數(shù)
    glutReshapeFunc(changeSize);
    //注冊顯示函數(shù)
    glutDisplayFunc(renderScene);
    //注冊特殊鍵位點擊回調(diào)函數(shù)
    glutSpecialFunc(specialKeyClick);
   
    //初始化一個GLEW庫,確保OpenGL API對程序完全可用扁瓢。
    GLenum status = glewInit();
    
    if (GLEW_OK != status) {
        printf("GLEW Error:%s\n",glewGetErrorString(status));
        return 1;
    }
    
    //設(shè)置我們的渲染環(huán)境
    setupRC();
    //這是?個?限執(zhí)?的循環(huán)伐债,它會負(fù)責(zé)?直處理窗?和操作系統(tǒng)的?戶輸?等操作
    glutMainLoop();
    
    return 0;
}

3.渲染之前需要進行清屏、初始化固定著色器以及設(shè)置頂點數(shù)據(jù)

void setupRC() {
 
    //設(shè)置窗口背景顏色
    glClearColor(0.98f, 0.5f, 0.3f, 1);
    
    //初始化固定著色器
    shaderManager.InitializeStockShaders();
    
    //設(shè)置圖元鏈接類型以及頂點個數(shù),GL_TRIANGLE_FAN代表以三角形扇形的方式連接頂點
    triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
    
    //拷貝頂點數(shù)據(jù)到批次類
    triangleBatch.CopyVertexData3f(vVerts);
    
    //配置完畢
    triangleBatch.End();
}

4.窗口改變大小時的回調(diào)函數(shù)

//窗口大小改變時附鸽,接受新的寬度和高度
void changeSize(int w, int h) {
    //設(shè)置GL視口位置以及大小
    glViewport(0, 0, w, h);
}

5.當(dāng)需要重新渲染圖形時的回調(diào)函數(shù)

void renderScene() {
    //清除一個或一組特定的緩存區(qū)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    
    //2.設(shè)置一組浮點數(shù)來表示紅色
    GLfloat vRed[] = {1.0, 0.0, 0.0, 0.5f};
    
    //傳遞到存儲著色器,即GLT_SHADER_IDENTITY著色器瞒瘸,這個著色器只是使用指定顏色以默認(rèn)笛卡爾坐標(biāo)系在屏幕上渲染幾何圖形
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
    
    //提交著色器
    triangleBatch.Draw();
    
    //在開始的設(shè)置openGL 窗口的時候坷备,我們指定要一個雙緩沖區(qū)的渲染環(huán)境。這就意味著將在后臺緩沖區(qū)進行渲染情臭,渲染結(jié)束后交換給前臺省撑。這種方式可以防止觀察者看到可能伴隨著動畫幀與動畫幀之間的閃爍的渲染過程。緩沖區(qū)交換平臺將以平臺特定的方式進行俯在。
    //將后臺緩沖區(qū)進行渲染竟秫,然后結(jié)束后交換給前臺
    glutSwapBuffers();
}

運行程序就會看到如下的運行結(jié)果:


運行結(jié)果

5.在特殊鍵位點擊回調(diào)函數(shù)里面編寫如下代碼

void specialKeyClick(int key, int x, int y) {
    //以D點為基準(zhǔn)坐標(biāo),來改變A朝巫、B鸿摇、C其他點坐標(biāo)的值
    GLfloat d_x = vVerts[9];
    GLfloat d_y = vVerts[10];
    
    
    if (key == GLUT_KEY_UP) { //上移
        d_y += 0.1;
        //判斷上移之后是否超出邊界石景,超出就緊貼上邊界
        if (d_y > 1) {
            d_y = 1;
        }
        
    } else if (key == GLUT_KEY_LEFT) { //左移
        d_x -= 0.1;
        
        //判斷左移之后是否超出邊界劈猿,超出就緊貼左邊界
        if (d_x < -1) {
            d_x = -1;
        }
        
    } else if (key == GLUT_KEY_RIGHT) { //右移
        d_x += 0.1;
        
        //判斷右移之后是否超出邊界,超出就緊貼右邊界
        if (d_x + lengthOfSide > 1) {
            d_x = 1 - lengthOfSide;
        }
        
    } else if (key == GLUT_KEY_DOWN) { //下移
        d_y -= 0.1;
        //判斷下移之后是否超出下邊界潮孽,超出就緊貼下邊界
        if (d_y - lengthOfSide < -1) {
            d_y = -1 + lengthOfSide;
        }
        
    }
    
    //重新設(shè)置移動后A點的坐標(biāo)
    vVerts[0] = d_x;
    vVerts[1] = d_y - lengthOfSide;
    
    //重新設(shè)置移動后B點的坐標(biāo)
    vVerts[3] = d_x + lengthOfSide;
    vVerts[4] = d_y - lengthOfSide;
    
    //重新設(shè)置移動后C點的坐標(biāo)
    vVerts[6] = d_x + lengthOfSide;
    vVerts[7] = d_y;
    
    //重新設(shè)置移動后D點的坐標(biāo)
    vVerts[9] = d_x;
    vVerts[10] = d_y;
    
    //重新拷貝新的頂點數(shù)據(jù)到批次類
    triangleBatch.CopyVertexData3f(vVerts);
    
    //發(fā)送通知揪荣,重新渲染圖形
    glutPostRedisplay();
}

運行看看效果如何吧~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市往史,隨后出現(xiàn)的幾起案子仗颈,更是在濱河造成了極大的恐慌,老刑警劉巖椎例,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挨决,死亡現(xiàn)場離奇詭異,居然都是意外死亡订歪,警方通過查閱死者的電腦和手機脖祈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刷晋,“玉大人盖高,你說我怎么就攤上這事⊙凼” “怎么了喻奥?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長捏悬。 經(jīng)常有香客問我撞蚕,道長,這世上最難降的妖魔是什么过牙? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任诈豌,我火速辦了婚禮仆救,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘矫渔。我一直安慰自己彤蔽,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布庙洼。 她就那樣靜靜地躺著顿痪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪油够。 梳的紋絲不亂的頭發(fā)上蚁袭,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音石咬,去河邊找鬼揩悄。 笑死,一個胖子當(dāng)著我的面吹牛鬼悠,可吹牛的內(nèi)容都是我干的删性。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼焕窝,長吁一口氣:“原來是場噩夢啊……” “哼蹬挺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起它掂,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤巴帮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后虐秋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榕茧,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年客给,在試婚紗的時候發(fā)現(xiàn)自己被綠了用押。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡起愈,死狀恐怖只恨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抬虽,我是刑警寧澤官觅,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站阐污,受9級特大地震影響休涤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一功氨、第九天 我趴在偏房一處隱蔽的房頂上張望序苏。 院中可真熱鬧,春花似錦捷凄、人聲如沸忱详。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匈睁。三九已至,卻和暖如春桶错,著一層夾襖步出監(jiān)牢的瞬間航唆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工院刁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糯钙,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓退腥,卻偏偏與公主長得像任岸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子阅虫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

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