1. 程式人生 > >OpenGL繪製幾何物體(特性)

OpenGL繪製幾何物體(特性)

幾何物體可以用點來描述,我們可以通過OpenGL的api來了解一下

幾何圖形型別

image

其中以glBegin開始,glEnd結束

下圖是採用不同型別的圖形效果

image

為了熟悉上訴圖形,下面來對每種圖形進行測試

建立基礎座標系

在畫圖之前,首先要先建立座標系,將以左下角為(0,0)點,如下圖

image

窗體的大小則作為修剪的範圍

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);
}


int 
main(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(); return
0; }

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 ();
}

image

點很小,幾乎看不見 
可以用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 ();
}

image

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 ();
}

image

注意:直線的繪製必須成對,一個點無法畫一條線,上面第7個點無法畫一條線 

用glLineWidth設定線的寬度,如將上面的直線的寬度改為5

image

畫點線(虛線,破折線)

上面畫的直線可以稱之為實線,除此之外還可以畫虛線,

glLineStipple用於設定直線的點線模式,其有兩個引數

第二個引數PATTERN是一個16進位制的數,或者是轉換為二進位制的16位序列(若不足16位,以0補完)

如glLineStipple (1, 0x0101);  /*  dotted  */

image

從低位開始(即右側的1開始),如果是1則繪製畫素,0則留空 
第一個引數是擴充套件因子,如上factor設定為2的話,那麼將繪製2個畫素,14個留空,可以觀察下面效果以瞭解擴充套件因子,效果如下 
image

來自百度百科解釋:

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);

效果如下

image

狀態管理

在繪製點畫線時,必須先開啟其效果(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 ();
}

image

如果換成GL_LINE_LOOP則效果如下

image

這篇將沒講完的幾個型別講完

畫三角形

畫三角形以不同頂點的連線有三種方式,但都是內部填充的方式

image

  1. GL_TRIANGLES如同GL_LINES一樣,第一個三角形的點是V0,V1,V2,第二個則是V3,V4,V5,即是一個3的倍數
  2. GL_TRIANGLE_STRIP的填充方式猶如放棄前一個頂點,如第一個三角形V0,V1,V2,第二個則是V1,V2,V3(捨棄V0)
  3. GL_TRIANGLE_FAN的填充方式將永遠以V0為起始點,如第一個三角形為V0,V1,V2,第二個則是V0,V2,V3

這裡就不自己畫了,上面的例子已經可以充分表達了

畫四邊形

有兩種方式

image

其區別與畫三角形相同,只不過STRIP是隔了2個頂點

畫多邊形

image

GL_POLYGON用於畫多邊形

多邊形無法繪製非凸多邊形,如下圖

image

但可以用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 ();
}

效果如下

image