開始學習用OpenGL,也就想顯示一些點,以為挺簡單的,哎,看了兩天才會畫三維的點,做個總結。
使用OpenGL的基本流程
int main(int argv, char *argc[]) { //初始化glut glutInit(&argv, argc); //初始化顯示模式 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); //設置窗口大小 glutInitWindowSize(800, 600); //創建窗口 glutCreateWindow("Point Demo"); //注冊回調函數 glutReshapeFunc(onChangeSize); glutDisplayFunc(onRender); glutSpecialFunc(onSpecialKeyFunc); setupRenderingContext(); glutMainLoop(); return 0; }
主要是glut庫進行了一些初始化操作,並注冊需要的回調函數(事件處理函數)。
glutReshapeFunc 窗口大小發生改變的時候調用注冊函數
glutDisplayFunc 顯示的時候調用的函數,各種的畫圖操作都在這里進行
glutSpecialFunc 特殊按鍵(上、下、左、右)按下時調用的函數
還有其他的一些回調函數,例如:窗口關閉時,這里不再一一贅述。
setupRenderingContext 設置渲染的上下文(渲染環境)
glutMainLoop 進入主消息循環
函數名稱的一個簡單說明glut開頭的是glut庫的一些函數,gl開頭的則是標准的OpenGL庫的函數。由於OpenGL沒有提供諸如窗口管理、輸入輸出以及按鍵等的處理函數,所以需要一些OpenGL的擴展庫
來處理這些操作,並且OpenGL官方也提倡開發一些擴展庫。glut是OpenGL中比較常見的一種。
回調函數及渲染環境設置
窗口大小改變時的回調函數
//窗口大小改變的回調函數 void onChangeSize(GLint w,GLint h){ //橫寬比 GLfloat ratio; //設置坐標系x(-100.0f,100.0f),y(-100.0f,100.0f),z(-100.0f,100.0f) GLfloat coordinateSize = 100.0f; //設置視口和窗口大小一樣 glViewport(0, 0, w, h); //對投影矩陣應用隨后的矩陣操作 glMatrixMode(GL_PROJECTION); //重置當前指定的矩陣為單位矩陣 glLoadIdentity(); ratio = (GLfloat)w / (GLfloat)h; //正交投影 if (w < h) glOrtho(-coordinateSize, coordinateSize, -coordinateSize / ratio, coordinateSize / ratio, -coordinateSize, coordinateSize); else glOrtho(-coordinateSize * ratio, coordinateSize * ratio, -coordinateSize, coordinateSize, -coordinateSize, coordinateSize); //對模型視圖矩陣堆棧應用隨后的矩陣操作 glMatrixMode(GL_MODELVIEW); //重置當前指定矩陣為單位矩陣 glLoadIdentity(); }
設置所使用的坐標系以及視口(viewport),坐標系、視口以及一些矩陣變換另作總結,這里不詳述。
Display時的回調函數
//渲染 void onRender(){ //清理 glClear(GL_COLOR_BUFFER_BIT); //將當前matrix狀態入棧 glPushMatrix(); glRotatef(xRotAngle, 1.0f, 0.0f, 0.0f); glRotatef(yRotAngle, 0.0f, 1.0f, 0.0f); glBegin(GL_POINTS); srand((unsigned)time(NULL)); GLfloat x, y, z; for (int i = 0; i < 1000; i ++){ x = rand() % 201 - 100; y = rand() % 201 - 100; z = rand() % 201 - 100; glVertex3f(x, y, z); } glEnd(); //恢復棧的Matrix glPopMatrix(); //交換兩個緩沖區 glutSwapBuffers(); }
生成1000個隨機的三維點,作圖的操作主要這里進行。
設置渲染環境
//設置Rendering context void setupRenderingContext() { //設置clear color為黑色 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //設置繪圖顏色 glColor3f(1.0f, 1.0f, 0.0f); }
設置了背景色以及繪圖的前景色
特殊按鍵回調函數
void onSpecialKeyFunc(GLint key, GLint x, GLint y){ if (key == GLUT_KEY_UP){ xRotAngle -= 5.0f; } else if (key == GLUT_KEY_DOWN){ xRotAngle += 5.0f; } else if (key == GLUT_KEY_LEFT){ yRotAngle -= 5.0f; } else if (key == GLUT_KEY_RIGHT){ yRotAngle += 5.0f; } //重新繪制 glutPostRedisplay(); }
按下上、下、左、右鍵時進行旋轉
結果
總結
簡單的OpenGL使用框架
//設置Rendering context void setupRenderingContext() { //設置clear color為黑色 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //設置繪圖顏色 glColor3f(1.0f, 1.0f, 0.0f); } //窗口大小改變的回調函數 void onChangeSize(GLint w,GLint h){ //橫寬比 GLfloat ratio; //設置坐標系x(-100.0f,100.0f),y(-100.0f,100.0f),z(-100.0f,100.0f) GLfloat coordinateSize = 100.0f; //設置視口和窗口大小一樣 glViewport(0, 0, w, h); //對投影矩陣應用隨后的矩陣操作 glMatrixMode(GL_PROJECTION); //重置當前指定的矩陣為單位矩陣 glLoadIdentity(); ratio = (GLfloat)w / (GLfloat)h; //正交投影 if (w < h) glOrtho(-coordinateSize, coordinateSize, -coordinateSize / ratio, coordinateSize / ratio, -coordinateSize, coordinateSize); else glOrtho(-coordinateSize * ratio, coordinateSize * ratio, -coordinateSize, coordinateSize, -coordinateSize, coordinateSize); //對模型視圖矩陣堆棧應用隨后的矩陣操作 glMatrixMode(GL_MODELVIEW); //重置當前指定矩陣為單位矩陣 glLoadIdentity(); } //渲染 void onRender(){ //清理 glClear(GL_COLOR_BUFFER_BIT); //TODO:主要操作在這里 //交換兩個緩沖區 glutSwapBuffers(); } int main(int argv, char *argc[]) { //初始化glut glutInit(&argv, argc); //初始化顯示模式 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); //設置窗口大小 glutInitWindowSize(800, 600); //創建窗口 glutCreateWindow("Point Demo"); //注冊回調函數 glutReshapeFunc(onChangeSize); glutDisplayFunc(onRender); setupRenderingContext(); glutMainLoop(); return 0; }