openGl学习之基本图元
從本篇開始,會給出一些代碼實例,所以要配置好編譯環境。
環境配置:
vs2012下配置鏈接http://www.cnblogs.com/dreampursuer/archive/2014/05/27/3754528.html
vc++6.0下配置鏈接http://blog.csdn.net/hbuxiaoshe/article/details/5047564
在給出詳細的畫圖代碼之前,先解說一下創建一個openGl程序窗體的初始化,在上一篇文章里已經介紹了,這里再貼一遍。
void display(void) {//這是我們自己的畫圖函數。我們在這里進行詳細地繪制。
} int main(int argc, char** argv) { glutInit(&argc, argv); //對GLUT進行初始化,必須一開始就初始化 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //設置顯示方式。參數之后再解釋 glutInitWindowPosition(100, 100); //設置程序窗體在屏幕中的位置 glutInitWindowSize(400, 400); //設置程序窗體的大小 glutCreateWindow("第一個OpenGL程序"); //給程序窗體加入標題 glutDisplayFunc(&display); //*調用我們自己的畫圖函數來繪制 glutMainLoop(); //啟動消息循環后程序執行起來 return 0; }
OpenGL的基本圖元有點(Point)、線段(Line)、多邊形(Ploygon)、三角形(Triangle)、四邊形(Quadrangle)。組成關系我想大部分人都可以理解:
①無數個“點”的線性排列組成----“線段”
②多個“線段”能夠圍成一個“多邊形”
③多個“多邊形”在三維空間中能夠圍成“多面體”
有此,能夠看出,點是最主要的圖元,其它的圖元都是由頂點組合構成的。因此我們從點開始介紹。
1、點
在OpenGL中,“點”稱為頂點(Vertex),通經常使用一個形如(x, y, z)的三維坐標值表示。
有時候會採用齊次坐標表示。就是一個形如(x, y, z, w)的四元組,能夠這樣理解這個四元組。前面的(x,y,z)表示“點”所在的方向。而w表示在該方向上的距離比例。所以(x, y, z, w)表示的實際坐標值就是(x/w, y/w, z/w)坐標點。假設w為0。則表示方向為(x, y, z)的無窮遠點;假設w=10,表示取(x,y,z)的十分之中的一個作為坐標點(x/10,y/10,z/10)。
普通情況 下,OpenGL 中的點將被畫成單個的像素。實際上點還能夠更小。盡管它可能足夠小,但并不會是無窮小,一個像素內能夠描繪多個點,取決于對點大小的設定。默認一個點的大小為一個像素。
當然我們也能夠改變點的大小,函數原型為:
//size 必須大于 0.0f,默認值為 1.0f,單位為“像素”。 //對于詳細的 OpenGL 實現,點的大小都有個限度的,假設設置的 size 超過最大值,則設置可能會有問題,普通情況是不在增大。void glPointSize(GLfloat size);
代碼實現畫一個點,我們僅僅須要在我們的畫圖函數中加入例如以下代碼就可以:
void display(void) {glPointSize(5);//在繪制之前要設置要相關參數,這里設置點的大小為5像素glBegin(GL_POINTS);{glVertex2f(0.0f, 0.0f); //OpenGl內的點是齊次坐標的四元組。缺省的z坐標為0.0f,w為1.0f,所以該點為(0, 0, 0, 1)glVertex2f(0.0f, 0.5f); //繪制的第二個點glVertex2f(0.5f, 0.25f); //繪制的第三個點}glEnd();glFlush();//glFlush,保證前面的OpenGL命令馬上運行(而不是讓它們在緩沖區中等待) }須要注意的是:坐標的值默認是1.0為最大,即屏幕邊緣,所以假設大于1。則會超出屏幕。這時候除非改變觀察點,否則是看不到的。(0,0)表示在屏幕的中間,也就是坐標系原點。
OpenGL中繪制幾何圖元,必須使用 glBegain() 和 glEnd() 這一對函數,glBegin() 和 glEnd() 須要成對使用,兩者之間是畫圖語句。
glBegin()的參數就是須要繪制的圖元類型,它決定了在glBegin()和glEnd()之間畫圖的點將怎樣組織成目標圖元,如參數為“GL_POINTS”,表示每個點都是獨立的,互不相連的。因此也就繪制出了一個個“點”。
2、線段
線段是由兩個頂點連接起來形成的圖元。線段間的連接方式有三種:
①獨立線段:圖元類型參數--GL_LINES
②線段間首尾相連但終于不閉合:折線,圖元類型參數--GL_LINE_STRIP
③線段間首尾相連終于封口閉合:圖形。圖元類型參數--GL_LINE_LOOP
相應的圖例:
?
線段代碼實例:
void display(void) {/*相同用5個點,畫出不同類型的線段組合*///獨立線段,5個點能畫出2條線段glBegin(GL_LINES);{glVertex2f(-0.8f, -0.5f); glVertex2f(-0.5f, -0.5f);glVertex2f(-0.8f, 0.0f); glVertex2f(-0.5f, 0.0f); glVertex2f(-0.8f, 0.5f); //最后的這個點沒有與之配對的點。無法連成線段。所以不會被畫出來,在獨立線段模式下被舍棄}glEnd();//連續不閉合折線,5個點能畫出4條線段glBegin(GL_LINE_STRIP);{glVertex2f(-0.3f, -0.5f); //起始點//后面的每個點都會與前一個相連生成一條線段glVertex2f(-0.0f, -0.5f);glVertex2f(-0.3f, 0.0f); glVertex2f(-0.0f, 0.0f); glVertex2f(-0.3f, 0.5f);}glEnd();//連續閉合折線,5個點能畫出5條線段glBegin(GL_LINE_LOOP);{glVertex2f(0.2f, -0.5f); //起始點//后面的每個點都會與前一個相連生成一條線段glVertex2f(0.5f, -0.5f);glVertex2f(0.2f, 0.0f); glVertex2f(0.5f, 0.0f); //最后一個點不僅與前一個點相連。還與起始點相連,形成閉合glVertex2f(0.2f, 0.5f);}glEnd();glFlush();//保證前面的OpenGL命令馬上運行(而不是讓它們在緩沖區中等待) }程序執行演示樣例圖:
相同的。直線能夠指定寬度:
void glLineWidth(GLfloat width); //width表示線寬,單位:像素特殊的是線除了直線。還有虛線。能夠用虛線連接兩個點。
在繪制虛線之前必須先啟動“虛線模式”:glEnable(GL_LINE_STIPPLE);
虛線有不同的類型。調節函數例如以下:
/*參數pattern是16位二進制數(0或1)。如OxAAAA表示1010101010101010從低位開始,每個二進制位代表一個像素。 1表示用當前顏色繪制一個像素。0表示當前不繪制,僅僅移動一個像素位,中間留下一個像素的空白factor是用來調節二進制位0和1代表的像素個數。假設factor為2,則表示遇到二進制1的時候用當前顏色繪制兩個像素,0移動兩個像素不繪制 */ void glLineStipple(GLint factor,GLushort pattern);代碼演示樣例:
void display(void) {//開啟虛線模式glEnable(GL_LINE_STIPPLE);//調節虛線類型參數glLineStipple(2,0xAAAA);//調節線寬glLineWidth(3);//繪制一條虛線glBegin(GL_LINES);{glVertex2f(0,0);glVertex2f(0.5,0.5);}glEnd();glFlush();//保證前面的OpenGL命令馬上運行(而不是讓它們在緩沖區中等待) }程序執行演示樣例:
3、多邊形
類似于點組合線段的方式。OpenGL定義的多邊形是由多個點連接成線段再圍成封閉區域。
多邊形有兩種:凸多邊形(指多邊形隨意非相鄰的兩點的連線位于多邊形的內部)和凹多邊形,但OpenGL中規定的多邊形必須是凸多邊形。
但有時須要繪制一些凹多邊形,通常解決的辦法是對它們進行切割。用多個三角形來組合替代。顯然,繪制這些三角形時。有些邊不應該進行繪制,否則,多邊形內部就會出現多余的線框。OpenGL提供的解決的方法是通過設置邊標志命令glEdgeFlag()來控制某些邊產生繪制。而另外一些邊不產生繪制。這里僅僅需知道有這個工能。詳細細節待遇到在研究,接下來看重點。
(1)連接方式
<1>按點的定義順序依次連接:圖元類型參數--GL_POLYGON
<2>從第1個點開始。每三個點一組畫一個三角形,三角形之間是獨立的:圖元類型參數--GL_TRIANGLES
<3>從第三個點開始,每點與前面的兩個點組合畫一個三角形,即線性連續三角形串:圖元類型參數--GL_TRIANGLE_STRIP
<4>從第三個點開始,每點與前一個點和第一個點組合畫一個三角形。即扇形連續三角形:圖元類型參數--GL_TRIANGLE_FAN
相應的圖例:
?
四邊形的繪制模式和三角形類似。
(2)多邊形的正反兩面
多邊形為什么會有正反面這一說法呢?舉個簡單的樣例。
盡管多邊形是二維的。可是我們知道三維物體能夠理解為多邊形圍成的,也就是說在三維空間物體上有二維多邊形的存在。
一張“正方形”紙片,假設極限的薄,我們能夠覺得是一個多邊形(正方形),那么紙仍然會存在兩面。紙的正反面。
更詳細一點。假設我們用同大小6張正方形的紙片圍成一個正方體,那么正方體的不論什么一個面都是一個多邊形,并且這個多邊形是有正反面。朝外的你能看到的部分是正面(假設),那么朝內的看不到的那部分就是反面。相同的道理,OpenGL要區分多邊形的正反面。
那么究竟怎么定義正面或者反面呢?
有一個函數來定義:
glFrontFace(GL_CCW);//設置點序列逆時針方向圍成的多邊形為正面 glFrontFace(GL_CW); //設置點序列順時針方向圍成的多邊形為正面設置這個的原因是。默認情況下,OpenGL繪制三維物體時兩面都會繪制。而實際的時候非常多面我們是看不到的。如物體朝內方向的多邊形。另一些物體間遮擋的情況導致有些多邊形是不可見的,因此為了提高性能,我們須要剔除這些不必要的繪制。
glEnable(GL_CULL_FACE); //來啟動剔除功能 glCullFace(); //參數能夠是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK,表示剔除多邊形的哪種面,設定后該類型的多邊形不繪制(3)繪制模式
經常使用的多邊形繪制模式有:填充式(默認)、輪廓線式、頂點式和鏤空圖案填充式。
前三種都是使用glPolygonMode()函數來指定模式,最后一種比較特殊。
void glPolygonMode(GLenum face,GLenum mode);//該函數要求說明是對多邊形哪一個面是定face設置模式
畫一個多邊形。設置不同的繪制模式,看一下效果:
代碼:
void myDisplay(void) {//設置點的大小,以便easy觀察glPointSize(5);//設置正面的繪制模式為:填充式,反面不設定則默覺得填充式glPolygonMode(GL_FRONT,GL_FILL);glBegin(GL_POLYGON);{glVertex2f(0,0);glVertex2f(0,0.3);glVertex2f(-0.3,0.3);glVertex2f(-0.3,0);}glEnd();//設置正面的繪制模式為:輪廓線式glPolygonMode(GL_FRONT,GL_LINE);glBegin(GL_POLYGON);{glVertex2f(0.5,0);glVertex2f(0.5,0.3);glVertex2f(0.2,0.3);glVertex2f(0.2,0);}glEnd();//設置正面的繪制模式為:頂點式glPolygonMode(GL_FRONT,GL_POINT);glBegin(GL_POLYGON);{glVertex2f(0.9,0);glVertex2f(0.9,0.3);glVertex2f(0.6,0.3);glVertex2f(0.6,0);}glEnd();glFlush(); }
演示樣例圖:
關于最后一種鏤空圖案樣式,有點類似于線段中的虛線,這里僅僅只是是針對多邊形內部區域進行像素點的繪制與否。來做鏤空效果。
詳細的細節還需查閱資料。
?
以上為基本圖元的知識解說,并給出了針對性的代碼實例,在此基礎之上會進一步學習更加復雜的圖形繪制。
?
?
轉載于:https://www.cnblogs.com/claireyuancy/p/6863644.html
總結
以上是生活随笔為你收集整理的openGl学习之基本图元的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转:WEB前端性能优化规则
- 下一篇: android WIFI信息获取