PyOpengl學習(三):繪製點、線、面(上)
今天我們來看一下在OpenGL中如何繪製點線面。
我們使用glBegin,和glEnd兩個函式進行所要繪製圖形的描述。繪製的內容要放在這兩個函式之間。
glBegin(GLenum mode);
//給出資料點
glEnd();
一,首先來了解一下OpenGl圖元的模式標識
點 GL_POINTS
線 GL_LINES
條帶線 GL_LINE_STRIP
迴圈線 GL_LINE_LOOP
獨立三角形 GL_TRIANGLES
三角形條帶 GL_TRIANGLE_STRIP
三角形扇面 GL_TRIANGLE_FAN
二、點
點,對應到螢幕上是一個畫素,它通過座標確定位置。通過呼叫glBegin()函式傳遞GL_POINTS引數,即可繪製點。
程式碼:
from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * def drawFunc(): glClearColor(0.0, 0.0, 0.0,0.0) glClear(GL_COLOR_BUFFER_BIT) glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0) # 設定點大小 glPointSize(5) # 只繪製端點 glBegin(GL_POINTS) # 第一個點 glColor3f(1.0, 0.0, 0.0) glVertex3f(0.25, 0.25, 0) # 第二個點 glColor3f(0.0, 1.0, 0.0) glVertex3f(0.75, 0.25, 0) # 第三個點 glColor3f(0.0, 0.0, 1.0) glVertex3f(0.75, 0.75, 0) # 第四個點 glColor3f(1.0, 1.0, 1.0) glVertex3f(0.25, 0.75, 0) glEnd() glFlush() if __name__ == '__main__': glutInit() glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA) glutInitWindowSize(400, 400) glutCreateWindow(b"First") glutDisplayFunc(drawFunc) glutMainLoop()
效果如下
這裡講解drawFunc()函式:
1,首先,我們要清除幀快取的資料再進行渲染。清除的工作由glClear(GL_COLOR_BUFFER_BIT)完成。
void glClear(GLbitfield mask);
清除指定的快取資料並重置為當前的清除值。mask是一個可以通過邏輯“或”操作來指定多個數值的引數,主要有三個:
顏色快取:GL_COLOR_BUFFER_BIT
深度快取:GL_DEPTH_BUFFER_BIT
模板快取:GL_STENCIL_BUFFER_BIT
2,如果要改變清除顏色的數值,可以使用glClearColor()
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
舉例說明清除顏色的用法,比如我們希望將當前視口的背景顏色設定為白色,那麼需要呼叫glClearColor(1, 1, 1, 1)。但是我們應該在什麼時候呼叫這個函式呢?當然,我們可以直接在drawFunc() 函式中呼叫glClear() 之前呼叫它。但是這樣的話,除了第一次進入迴圈之時,其他所有對glClearColor() 的呼叫都是多餘的—因為OpenGL 在每次渲染時都會重複設定清除顏色的狀態值為白色。另一個效率更高的方法是在init() 函式中設定清除顏色。事實上,這樣我們就可以避免冗餘的狀態切換;所有在程式執行時不會發生變化的數值都應該在init() 中設定。當然,冗餘的函式呼叫本身並沒有危害,但是它會造成程式執行速度稍微變慢。
3,畫點
畫點操作從 glBegin(GL_POINTS)開始,到glEnd()結束
glColor3f(1,0,0)用來設定顏色。
glVertex3f(0,0,0)用來畫點。
glPointSize(5)來設定圓點半徑大小
4,glFlush()
最後在drawFunc()函式中呼叫glFunc(),即強制所有進行中的OpenGL 命令立即完成並傳輸到OpenGL 服務端處理。
三、線
線的繪製和點差不多
def drawLine():
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0.0, 1.0, 0.0)
glLineWidth(2)
glBegin(GL_LINES)
glVertex3f(-0.5, -0.5, 0.0)
glVertex3f(-0.5, 0.5, 0.0)
glVertex3f(0.5, -0.5, 0.0)
glVertex3f(0.5, 0.5, 0.0)
glEnd()
glFlush()
效果:
通過glLineWidth(2)設定線段的寬度,glVertex3f(-0.5, -0.5, 0.0)設定線段的端點
由於一條線段有兩個端點,所以glVertex3f()成對出現,如果改動上面的程式碼上如下
def drawLine():
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0.0, 1.0, 0.0)
glLineWidth(2)
glBegin(GL_LINES)
glVertex3f(-0.5, -0.5, 0.0)
glVertex3f(-0.5, 0.5, 0.0)
glVertex3f(0.5, -0.5, 0.0)
glVertex3f(0.5, 0.5, 0.0)
glVertex3f(0.0, 0.0, 0.0)
glEnd()
glFlush()
則顯示結果和上面的是一樣的。
前面我們已經提到線主要有三種,上面的是一種還有條帶線(GL_LINE_STRIP)和迴圈線(GL_LINE_LOOP)
上面的程式碼,我們把GL_LINES改為GL_LINE_STRIP
結果為:
把GL_LINES改為GL_LINE_LOOP結果為: