編程學習網 > 編程語言 > Python > Python OpenGL繪制三大要素教程
2023
09-19

Python OpenGL繪制三大要素教程

盡管我們一直呼吁小伙伴們不要將OpenGL狹義地理解為繪制或者渲染API,但是在 OpenGL 3.2 Compute Shader未面世之前,它本質上確實是一套圖形圖像渲染的API。從功能上說,它的主要作用就是完成圖形圖像渲染,不管是UI界面的繪制,還是各大游戲引擎渲染,背后都是通過它來實現的。更重要的是,繪制或渲染的三大要素------畫筆、畫布、繪制方式它都一一具備,并且組成成分能夠完全對應他們。

本篇將圍繞繪制三大要素給小伙伴們講述OpenGL中的繪制基本概念。我們首先會對畫筆進行講述,這小節是對頂點著色器的回顧,同時也會告訴大家另一種輕量的畫筆;然后,我們將簡單講述畫布,讓大家對渲染窗口和視圖窗口有更深層次的理解;接下來,我們會對繪制方式進行詳細講解,本小節也會讓大家了解OpenGL中的基本形狀。
畫筆
不管是小伙伴們玩的酷炫游戲,還是在視頻應用上看到的精美電視劇,它們都有著優美的畫面。這些優美畫面的展示和畫筆息息相關。顯示屏上每一個像素點的最終上色都由它完成,同時畫筆的智能與否也決定了顏色是否精彩紛呈。
在OpenGL中,畫筆主要由片段著色器所承擔。在光柵化之后,畫布被切割成了單個像素,每個像素都會交由一個片段器著色。所以大家也知道了,片段著色器這個畫筆的精度非常之高,它的粒度細到每一個像素點。此外,它也是一個非常智能的畫筆工具,它能夠接受用戶輸入結合自定義函數計算出每一個像素點的最終顏色并上色。
然而,相比于片段著色器,另外一種畫筆就很容易被小伙伴們忽略了,那就是一些顏色清除API。它對我們也至關重要,某些特定場景的高性能繪制離不開它。
現實中我們常常會有添加背景的需求,比如我們需要對某個UI控件添加白色或黑色的背景。這自然是可以通過著色器來實現的,但是小伙伴肯定也意識到了,殺雞焉用牛刀,這么一個簡單的繪制不應該由著色器這個復雜的畫筆出場。這時候,OpenGL API中提供的一些顏色清除API就派上用場了,能夠讓大家快速、方便、高性能完成背景顏色的繪制。
glClearColor(0.0,0.0,0,1.0);  
glClear(GL_COLOR_BUFFER_BIT)
僅僅通過上面兩行代碼,我們就能完成背景顏色的繪制。這兩行代碼最終會將畫布背景變成黑色。第一行代碼是設置清除顏色,glClearColor函數的四個參數分別對應顏色的R、G、B、A四個分量。大家在實際開發中應該謹記,第一行代碼僅僅是一個顏色設置函數,它無法單獨實現背景顏色的更新,真正實現更新的是第二行代碼。glClear這個函數只有一個參數,通過這個參數指定需要清除的緩沖區,一般來說,我們需要清除顏色緩沖區來更新背景顏色,因此會設置成例子中的GL_COLOR_BUFFER_BIT參數。兩行代碼結合使用之后,畫布的背景就被更新成了黑色。
畫布
好比畫畫,僅有畫筆是不夠的。真正開始畫畫之前,我們需要做一些準備操作的,除了提供畫筆,也要提供一張畫紙當作畫布,這樣才有地方給我們繪制。在OpenGL中,渲染窗口就是這樣一張畫布。當我們創建了渲染窗口,我們就有了畫布,我們的繪制操作才會有空間承載,進而顯示給用戶。
然而,我們必須要說明的是渲染窗口無法完美對應OpenGL中畫布這一概念。比如在Android中,我們通過本地窗口Surface創建渲染窗口,但是如果沒有通過glViewPort函數設置視圖窗口,那么顏色清除接口就不會在渲染窗口中生效。由此看來,OpenGL中和畫布最貼切的應該是視圖窗口。
理解了這一點,那小伙伴們應該對渲染窗口和視圖窗口有了更為深層次的理解。渲染窗口就好比一張紙,這張紙我們可以全部用作畫布,也可以把部分區域折疊起來用剩下的部分當作畫布。glViewPort函數就是這個折疊工具。通過它提供的偏移以及寬高參數設置,我們就能獲得真正的畫布。
繪制方式及基本形狀
現在我們已經有了畫筆和畫布,萬事俱備,要開始進行正式的畫畫了。擺在我們面前首當其沖的是要解決“如何畫”這個難題。
“如何畫”這個任務其實從本質上來說就是要將這些頂點轉化為具體的形狀。我們前文中說,通過頂點數組就能確定繪制區域,其實這是一個不嚴謹的表述??陀^世界中的基本形狀多種多樣,包括點、線、三角形、矩形、多邊形等等,所以繪制區域其實是沒有辦法由這些頂點數組單獨確定的,它可能是這些頂點數組對應的點,也可能是由這些頂點數組連接而成的線,當然更常見的是由頂點數組勾勒而成的三角形、矩形、多邊形區域。光有頂點數組不指定目標形狀,頂點數組勾勒出的區域就不具備確定性。一個由三個點組成的頂點數組,你既可以用來繪制三角形的三個頂點,也可以用于繪制三角形的三條邊,當然也可以用于繪制三角形。
此外,這些形狀是由哪些點組成、并以什么順序連接,這些信息都是繪制必要信息。這些形狀的具體轉化方式僅僅通過頂點數組也是無法獲得的,我們不知道有頂點數組中有哪些頂點實際參與了這些形狀的轉化,也不知道他們會以什么順序參與轉化,而后者關乎到的是取樣區域,如果弄錯,繪制出來的畫面必然錯位。
針對這些問題,OpenGL中有著明確的規范。針對目標形狀,在OpenGL規范中只有點、線、三角形這三個基本形狀(準確地說是OpenGLES,桌面端OpenGL的基礎形狀還包括多邊形),其他形狀都是由這些基本形狀拼接而成,比如一個矩形就是由兩個三角形拼接而成。至于“由哪些點組成、并以什么順序連接”這個問題,glDraw**這些繪制函數本身就予以了回答。通過繪制函數的offset、first、count這些參數應用程序能夠指定參與繪制區域的頂點,而通過mode參數指明的繪制方式,我們不僅能確定這些頂點勾勒出來的目標區域是什么形狀,同時也能指定這些頂點的連接順序。
由mode參數確定的繪制方式在OpenGL(準確地說是OpenGLES)中有以下幾種模式:
public static final int GL_POINTS                    =0x0000;
public static final int GL_LINES                     =0x0001;
public static final int GL_LINE_LOOP                 =0x0002;
public static final int GL_LINE_STRIP                =0x0003;
public static final int GL_TRIANGLES                 =0x0004;
public static final int GL_TRIANGLE_STRIP            =0x0005;
public static final int GL_TRIANGLE_FAN              =0x0006;
下面,我們會對這些模式一一進行講解,我們將以頂點數組[V0,V1,V2,V3,V4,V5]來進行演示
點繪制

通過將mode設置為GL_POINTS,我們就能繪制頂點數組中的每個頂點。點繪制如下圖所示:               

線繪制
在OpenGL中,線表示一條線段。一條線段可以通過兩個頂點來表達,多段線可以使用多個線段鏈接來表示,首尾閉合的多段線叫循環線。OpenGL中的線繪制有三種模式,分別是GL_LINES、GL_LINE_STRIP、GL_LINE_LOOP,它們分別代表了不連接線段、多條線段連接、多條線段連接再首尾相連這三種線段繪制方式,如下所示:
GL_LINES

GL_LINE_STRIP

GL_LINE_LOOP
       
三角形繪制
OpenGL中也提供了三種繪制三角形的方式,分別是GL_TRIANGLES、GL_TRIANGLE_STRIP和GL_TRIANGLE_FAN。
GL_TRIANGLES
三種模式中最為常見的是GL_TRIANGLES。它標志著將用頂點數組每三個頂點為一個繪制單元繪制一個三角形。以頂點數組[V0,V1,V2,V3,V4,V5]為例,這種模式下將繪制兩個三角形。第一個三角形的頂點排列順序是[v0,v1,v2],第二個三角形的頂點排列順序為[v3,v4,v5]。
     
GL_TRIANGLE_STRIP
GL_TRIANGLE_STRIP和GL_TRIANGLES較為類似,所不同的是頂點數組中的頂點會被重復使用。它構建三角形的規則如下:
除了首個三角形,后續三角形都會復用前面三角形的兩個頂點;
當前頂點結合復用的兩個頂點構成三角形的順序依賴當前這個頂點的奇偶性(頂點索引從0開始)。如果當前頂點是奇數,那么組成三角形的頂點排列順序為[n-1,n-2,n],其中n為當前頂點,n-1和n-2是前面三角形已經用過的頂點;反之,如果當前頂點是偶數,組成三角形的頂點排列順序是[n-2, n-1,n]。
     
以上圖為例,第一個三角形定點排列順序是[v0,v1,v2],第二個三角形復用第一個三角形的后面兩個頂點,同時,由于當前頂點索引是3,3是奇數,則頂點排列順序是[v2,v1,v3],到了第三個三角形,由于頂點v4序號是4,4是偶數,因此頂點排列順序是變為[v2,v3,v4],最后一個三角形頂點是奇數,排練順序是[v4, v3, v5]。
GL_TRIANGLE_FAN
GL_TRIANGLE_FAN較為少見,一般用于畫多邊形或者圓。定點數組的首個頂點將固定下來,之后每次取兩個頂點與之構建三角形,如下圖所示:

小伙伴在OpenGL開發中要了解這些模式,并且按照這些模式指定的繪制順序進行繪制。

以上就是Python OpenGL繪制三大要素教程的詳細內容,想要了解更多Python教程歡迎持續關注編程學習網。

掃碼二維碼 獲取免費視頻學習資料

Python編程學習

查 看2022高級編程視頻教程免費獲取