OpenGL繪製幾何物體(特性)
幾何物體可以用點來描述,我們可以通過OpenGL的api來了解一下
幾何圖形型別
其中以glBegin開始,glEnd結束
下圖是採用不同型別的圖形效果
為了熟悉上訴圖形,下面來對每種圖形進行測試
建立基礎座標系
在畫圖之前,首先要先建立座標系,將以左下角為(0,0)點,如下圖
窗體的大小則作為修剪的範圍
void reshape (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h); } intmain(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (400, 150); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return0; }
GL_POINTS
Draws a point at each of the n vertices.
畫7個點
示例1
void drawPoint1(void) { int i; glColor3f (0.0, 0.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 7; i++) glVertex2f (20.0 + ((GLfloat) i * 20.0), 50.0); glEnd (); }
點很小,幾乎看不見
可以用glPointSize調整point的大小,如下。現在看起來清晰多了
示例2
void drawPoint2(void) { int i; glColor3f (0.0, 0.0, 0.0); glPointSize(5); glBegin(GL_POINTS); for (i = 0; i < 7; i++) glVertex2f (20.0 + ((GLfloat) i * 20.0), 60.0); glEnd (); }
GL_LINES
Draws a series of unconnected line segments.Segments are drawn between v0 and v1,between v2 and v3, and so on. If n is odd, the last segment is drawn between vn–3 and vn–2,and vn–1 is ignored.
如果將示例1的GL_POINTS更改為GL_LINES,那麼將會有三條線,如下
示例3
void drawLine1(void) { int i; glColor3f (0.0, 0.0, 0.0); glBegin(GL_LINES); for (i = 0; i < 7; i++) glVertex2f (20.0 + ((GLfloat) i * 20.0), 60.0); glEnd (); }
注意:直線的繪製必須成對,一個點無法畫一條線,上面第7個點無法畫一條線
用glLineWidth設定線的寬度,如將上面的直線的寬度改為5
畫點線(虛線,破折線)
上面畫的直線可以稱之為實線,除此之外還可以畫虛線,
glLineStipple用於設定直線的點線模式,其有兩個引數
第二個引數PATTERN是一個16進位制的數,或者是轉換為二進位制的16位序列(若不足16位,以0補完)
如glLineStipple (1, 0x0101); /* dotted */
從低位開始(即右側的1開始),如果是1則繪製畫素,0則留空
第一個引數是擴充套件因子,如上factor設定為2的話,那麼將繪製2個畫素,14個留空,可以觀察下面效果以瞭解擴充套件因子,效果如下
來自百度百科解釋:
viod glLineStipple(glint factor,GLshort pattern);
OpenGL中設定直線的當前點畫模式。pattern引數是由1或0組成的16位序列,它們根據需要進行重複,對一條特定的直線進行點畫處理。從這個模式的低位開始,一個畫素一個畫素的進行處理。如果模式中對應的位是1,就繪製這個畫素,否則就不繪製。模式可以使用factor引數(表示重複因子)進行擴充套件,它與1和0的連續子序列相乘。因此,如果模式中出現了3個1,並且factor是2,那麼它們就擴充套件為6個連續的1。必須以GL_LINE_STIPPLE為引數呼叫glEnable()才能啟用直線點畫功能。為了禁用直線點畫功能,可以向glDisable()函式傳遞同一個引數
如下示例4
glEnable (GL_LINE_STIPPLE); glColor3f (0.0, 0.0, 0.0); glLineStipple (1, 0x0101); /* dotted */ drawOneLine (50.0, 125.0, 150.0, 125.0); glLineStipple (1, 0x00FF); /* dashed */ drawOneLine (150.0, 125.0, 250.0, 125.0); glLineStipple (1, 0x1C47); /* dash/dot/dash */ drawOneLine (250.0, 125.0, 350.0, 125.0); ///* in 2nd row, 3 wide lines, each with different stipple */ glLineWidth (5.0); glLineStipple (1, 0x0101); /* dotted */ drawOneLine (50.0, 100.0, 150.0, 100.0); glLineStipple (1, 0x00FF); /* dashed */ drawOneLine (150.0, 100.0, 250.0, 100.0); glLineStipple (1, 0x1C47); /* dash/dot/dash */ drawOneLine (250.0, 100.0, 350.0, 100.0); glLineWidth (1.0); ///* in 4th row, 6 independent lines with same stipple */ for (i = 0; i < 6; i++) { drawOneLine (50.0 + ((GLfloat) i * 50.0), 50.0, 50.0 + ((GLfloat)(i+1) * 50.0), 50.0); } // ///* in 5th row, 1 line, with dash/dot/dash stipple */ ///* and a stipple repeat factor of 5 */ glLineStipple (5, 0x1C47); /* dash/dot/dash */ drawOneLine (50.0, 25.0, 350.0, 25.0); glDisable (GL_LINE_STIPPLE);
效果如下
狀態管理
在繪製點畫線時,必須先開啟其效果(glEnable),在使用完畢後關閉效果(glDisable )
如上面程式碼,在最開始的時候則呼叫glEnable (GL_LINE_STIPPLE)方法,結束後則呼叫glDisable (GL_LINE_STIPPLE);
GL_LINE_STRIP和GL_LINE_LOOP
GL_LINE_STRIP用於點之間的連線,GL_LINE_LOOP則在STRIP的基礎上同時將第1個點和最後一個點連起來
示例5
void drawLineStrip()
{
glColor3f (0.0, 0.0, 0.0);
glPointSize(5);
glBegin(GL_LINE_STRIP);
glVertex2i(20,20);
glVertex2i(30,50);
glVertex2i(100,80);
glVertex2i(120,40);
glVertex2i(10,40);
glEnd ();
}
如果換成GL_LINE_LOOP則效果如下
這篇將沒講完的幾個型別講完
畫三角形
畫三角形以不同頂點的連線有三種方式,但都是內部填充的方式
- GL_TRIANGLES如同GL_LINES一樣,第一個三角形的點是V0,V1,V2,第二個則是V3,V4,V5,即是一個3的倍數
- GL_TRIANGLE_STRIP的填充方式猶如放棄前一個頂點,如第一個三角形V0,V1,V2,第二個則是V1,V2,V3(捨棄V0)
- GL_TRIANGLE_FAN的填充方式將永遠以V0為起始點,如第一個三角形為V0,V1,V2,第二個則是V0,V2,V3
這裡就不自己畫了,上面的例子已經可以充分表達了
畫四邊形
有兩種方式
其區別與畫三角形相同,只不過STRIP是隔了2個頂點
畫多邊形
GL_POLYGON用於畫多邊形
多邊形無法繪製非凸多邊形,如下圖
但可以用glPolygonMode函式改變多邊形繪製的模式,繪製其輪廓
void drawpolygon()
{
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glColor3f (0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex2i(20,20);
glVertex2i(30,10);
glVertex2i(100,50);
glVertex2i(120,100);
glVertex2i(50,120);
glVertex2i(50,60);
glEnd ();
}
效果如下