CS184.1X 計算機圖形學導論 第6講 學習筆記
L6V1:OPENGL 1:概述
1.OpenGL簡介
1)圖形程式設計介面(Graphics API),介於程式設計者和實際的圖形硬體;
2)執行的統一指令集具有可移植性。
2.為什麼需要OpenGL?
面向三維計算機圖形的高階語言,具備許多2D/3D圖形的基本處理功能。
3.OpenGL渲染管線
OpenGL具備對圖形和影象的初始處理功能,其實際上是一個使用掃描轉換器的光柵化程式。主流程第一步,針對圖形,首先利用頂點著色器進行幾何初始運算處理,而影象,則是進行畫素操作;第二步則是進行掃描轉換(光柵化),確定螢幕上圖形頂點所具體對應的畫素;主流程第三步,片元操作,確定每個形狀的可見畫素的輸出顏色,最後輸出到幀快取。
L6V2:OPENGL 1:快取和矩陣
1.快取分類 :顏色快取(GLUT_RGB)、深度快取(GLUT_DEPTH)、累積快取(GLUT_ACCUM)、模板快取(GLUT_STENCIL)、單快取(GLUT_SINGLE)、雙快取(GLUT_DOUBLE);
2.為了 移植性 ,OpenGL沒有包含任何視窗系統互動的特性;但可以使用替代品:GLUT和一些其它的工具包(Motif、GLX、Tcl/Tk),均實現了回撥,可以相應滑鼠和鍵盤訊息。
3.基本模式設定:
1 int main(int argc, char** argv) 2 { 3... 4 5glutInit(&argc, argv); 6 7// Requests the type of buffers (Single, RGB). 8// Think about what buffers you would need... 9 10glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 11 12glutInitWindowSize (500, 500); 13glutInitWindowPosition (100, 100); 14glutCreateWindow ("Simple Demo with Shaders"); 15 16GLenum err = glewInit() ; 17if (GLEW_OK != err) { 18std::cerr << "Error: " << glewGetString(err) << std::endl; 19} 20 21init(); 22 23... 24 }
4.訊息回撥:
1// Now, we define callbacks and functions for various tasks. 2glutDisplayFunc(display); 3glutReshapeFunc(reshape) ; 4glutKeyboardFunc(keyboard); 5glutMouseFunc(mouse) ; 6glutMotionFunc(mousedrag) ;
5.檢視 (取決於物體位置和攝像機的屬性)
1)兩種矩陣棧(舊式風格):GL_MODELVIEW_MATRIX、GL_PROJECTION_MATRIX,用於物體和攝像機的矩陣變換;
2)一般情況下,攝像機位於座標系原點上,朝向-Z方向;
3)在OpenGL中,矩陣元素儲存是列優先的;在新的GLM中,矩陣元素儲存為行優先,在編碼中需要重點注意;
6.Base initialization code for viewing
1 void init (void) 2 { 3... 4 5/* select clearing color*/ 6glClearColor (0.0, 0.0, 0.0, 0.0); 7 8/* initialize viewing values*/ 9glMatrixMode(GL_PROJECTION); 10glLoadIdentity();//讀入單位矩陣 11 12// Think about this.Why is the up vector not normalized? 13glMatrixMode(GL_MODELVIEW) ; 14glLoadIdentity() ;//讀入單位矩陣 15 16gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ;//OpenGL會自動進行單位化 17 18... 19 }
L6V3:OPENGL 1:視窗系統互動和回撥函式
1.視窗系統互動 -> GLUT (Not part of OpenGL)
2.reshape()和mousedrag()
1)reshape( )始終保持投影區域的寬高比與視窗一致
1 void reshape(int w, int h) 2 { 3windowWidth = w; 4windowHeight = h; 5glViewport (0, 0, (GLsizei) w, (GLsizei) h); 6glMatrixMode(GL_PROJECTION); 7glLoadIdentity(); 8gluPerspective(30.0, (GLdouble)w/(GLdouble)h, 1.0, 10.0) ; 9 }
2)mousedrag( ):通過按住滑鼠鍵拖動,來修改攝像機座標來實現縮放功能
1 void mousedrag(int x, int y) { 2int yloc = y - mouseoldy;// We will use the y coord to zoom in/out 3eyeloc+= 0.005*yloc ;// Where do we look from 4if (eyeloc < 0) eyeloc = 0.0 ; 5mouseoldy = y ; 6 7/* Set the eye location */ 8glMatrixMode(GL_MODELVIEW) ; 9glLoadIdentity() ; 10gluLookAt(0,-eyeloc,eyeloc,0,0,0,0,1,1) ; 11 12glutPostRedisplay() ; 13 }
其中, glutPostRedisplay()告訴GLUT儘可能快地排隊等候顯示函式,然後重繪場景進行顯示。
L6V4:OPENGL 1:繪製
1.Geometry:
1)Point(GL_POINTS);
2)Line segments(GL_LINES);
3)Polygons(複雜圖形採用GLU進行三角化);
4)其他特殊圖形(GLUT引入),如Sphere、teapot、cube。
2.舊式繪製方法 (採用客戶伺服器模型形式) ->易上手
1)將頂點新增在 glBegin()...glEnd()中間;
2)在定義頂點前,必須先定義顏色;
1 void display(void){ 2glClear(GL_COLOR_BUFFER_BIT); 3 4glBegin(GL_POLYGON); 5 6glColor3f(1.0, 0.0, 0.0); 7glVertex3f(0.5, 0.5, 0.0); 8glColor3f(0.0, 1.0, 0.0); 9glVertex3f(-0.5, 0.5, 0.0); 10glColor3f(0.0, 0.0, 1.0); 11glVertex3f(-0.5, -0.5, 0.0); 12glColor3f(1.0, 1.0, 1.0); 13glVertex3f(0.5, -0.5, 0.0); 14 15glEnd(); 16glFlush(); 17 }
其中, glFlush( )為同步指令,清理佇列。
3.新式繪製方法 (Vertex Buffer Objects)
1)定義多種型別的資訊,分為頂點陣列、顏色陣列、索引陣列;
2)建立頂點快取物件、圖元型別、快取偏移量;
3)繫結快取;
備註:此處詳細看作業程式碼部分。
L6V5:OPENGL 1:初始化著色器
1.步驟:
1)Create shader(Vertex and Fragment);
2)Compile shader;
3)Attach shader to program;
4)Link program;
5)Use program。