OpenGL學習筆記(2)

這次的筆記,我們通過一個OpenGL的一個簡單使用案例,并結(jié)合上個筆記中的名詞解釋,來看看它是如何繪制渲染到屏幕的。實現(xiàn)效果為繪制一個正方形,并可以通過鍵盤控制正方形移動。

案例的大致執(zhí)行流程可分為main->SetupRC->changeSize->RenderScene。

首先我們需要做一些準備工作,這里我們引入了OpenGL繪制所需要用到的幾個頭文件,并定義了一個著色管理器和一個批次類

image

main

main函數(shù)中我們主要用來初始化OpenGL環(huán)境變量,設置窗口,標題,注冊一些回調(diào)函數(shù)等

int main(int argc, char* argv[])
{
    gltSetWorkingDirectory(argv[0]);
    glutInit(&argc, argv);
    //申請一個顏色緩存區(qū)、深度緩存區(qū)、雙緩存區(qū)、模板緩存區(qū)
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    //設置window 的尺寸
    glutInitWindowSize(800, 600);
    //創(chuàng)建window的名稱
    glutCreateWindow("GL_POINTS");
    //注冊回調(diào)函數(shù)(改變尺寸)
    glutReshapeFunc(ChangeSize);
    //點擊空格時,調(diào)用的函數(shù)
    glutKeyboardFunc(KeyPressFunc);
    //特殊鍵位函數(shù)(上下左右)
    glutSpecialFunc(SpecialKeys);
    //顯示函數(shù)
    glutDisplayFunc(RenderScene);
    
    //判斷一下是否能初始化glew庫,確保項目能正常使用OpenGL 框架
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
        return 1;
    }
    
    //繪制
    SetupRC();
    
    //runloop運行循環(huán)
    glutMainLoop();
    return 0;
}

SetupRC

觸發(fā)條件:手動main函數(shù)觸發(fā)
處理業(yè)務:1.設置窗口背景顏色
2.初始化存儲著色器shaderManager
3.設置圖形頂點數(shù)據(jù)
4.利用GLBatch三角形批次類,將數(shù)據(jù)傳遞到著色器

void setupRC(){
    //設置清屏顏色(背景顏色)
    glClearColor(0.98f, 0.40f, 0.7f, 1);
    
    //沒有著色器,在OpenGL 核心框架中是無法進行任何渲染的。初始化一個渲染管理器。
    shaderManager.InitializeStockShaders();
    
    //修改為GL_TRIANGLE_FAN ,4個頂點
    triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
}

changeSize

觸發(fā)條件:當屏幕大小發(fā)生改變/第一次創(chuàng)建窗口時,會調(diào)用
處理業(yè)務:1.設置OpenGL視口
2.設置OpenGL投影方式等

void ChangeSize(int w,int h){
    if (h==0) {
        h=1;
    }
    glViewport(0,0, w, h);//設置視口
}

RenderScene

自定義函數(shù),通過glutDisplayFunc(函數(shù)名)注冊為顯示渲染函數(shù),當屏幕發(fā)生變化/或者開發(fā)者主動渲染會調(diào)用此函數(shù),用來實現(xiàn)數(shù)據(jù)->渲染的過程
觸發(fā)條件:1.系統(tǒng)自動觸發(fā) 2.手動調(diào)用函數(shù)觸發(fā)
處理業(yè)務:1.清理緩存區(qū)(顏色,深度,模版緩存區(qū)等)
2.使用存儲著色器
3.繪制圖形

void RenderScene(void){
    //清除緩存區(qū)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    //設置一組浮點數(shù)來表示紅色
    GLfloat vRed[] = {1.0,0.0,0.0,1.0f};
    //4x4矩陣
    M3DMatrix44f mTransfromMatrix;
    //平移
    m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);
   //將矩陣結(jié)果 提交給固定著色器(平面著色器)中繪制            
    shaderManager.UseStockShader(GLT_SHADER_FLAT,mFinalTransform,vRed);
    //提交著色器
    triangleBatch.Draw();
    //將后臺緩沖區(qū)進行渲染,然后結(jié)束后交換給前臺
    glutSwapBuffers();   
}

SpecialKeys

自定義函數(shù),這是我們在main()中添加的對鍵盤按鈕點擊后的監(jiān)聽回調(diào),在這里可以判斷我們點擊了鍵盤上的哪個鍵。xPos,yPos為x軸,y軸上的偏移量

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;
    }
    //碰撞檢測
    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;
    }
    //這是觸發(fā)重繪的一個API,類似于調(diào)用setNeedsDisplay()
    glutPostRedisplay();
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容