• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 【譯】【PyOpenGL教程-著色器簡介】 第一步(基本幾何)

    原文地址:http://pyopengl.sourceforge.net/context/tutorials/shader_1.html

    第一步(基本幾何)

    在本教程中我們將會學到:
    - 頂點著色器在GLSL中“必須”做什么
    - 片元著色器“必須”做什么
    - 什么是VBO對象
    - 如何**和停用著色器和VBO
    - 如何渲染簡單的幾何體

    image

    首先我們進行imports,OpenGLContext testingcontext允許PyGame、wxPython者GLUT GUI使用相同的代碼。這些imports將為機器檢索合適的上下文環境,如果你沒有安裝任何額外的依賴包,比如說Pygame或者wxPython,將會為你的機器提供一個GLUT上下文。

    from OpenGlContext import testingcontext
    BaseContext = testingcontext.getInteractive()

    現在導入我們將要使用的PyOpenGL功能。
    OpenGL.GL包含標準OpenGL函數,更詳細的信息可以閱讀PyOpenGL的手冊頁。

    from OpenGL.GL import *

    OpenGL.arrays.vbo.VBO類是一個方便的包裝器,它使得從PyOpenGL中使用頂點緩沖區對象變得更容易。它負責確定要使用哪個實現,創建偏移對象,甚至是基于基本切片的VBO中內容的更新。

    from OpenGL.arrays import VBO

    OpenGLContext.arrays只是一個抽象點,它可以導入Numpy(首選)或具有一些兼容性函數的舊數字庫,以使Numeric看起來像新的Numpy模塊。

    from OpenGLContext.arrays import*

    OpenGL.GL.shaders是一個用于訪問著色器功能的便利庫。

    from OpenGL.GL import shaders

    OpenGLContext contexts是Context的所有子類的合集,包含各種混合插件為不同的窗口類型,不同的交互機制等提供支持。這里的BaseContext是我們上面導入的TestingContext。

    class TestContext(BaseContext):
        """Creates a simple vertex shader"""

    OnInit方法是在已經成功創建了一個有效的OpenGL渲染上下文之后調用的。在OpenGL context被創建之前,你必須非常小心,不要調用(大多數)OpenGL接口(如果不能遵守這條規則通常會導致segfault或其他極端行為)。

        def OnInit(self):

    OpenGL.GL.shaders.compileProgram函數是一個方便的函數,它執行許多基本操作,用于抽象出很多著色器設置的復雜性。GLSL Shaders開始作為OpenGL的擴展,后來成為Core OpenGL的一部分,但有些驅動程序不支持“核心”版本的著色器API。這種擴展機制是擴展OpenGL的“正常”方式,但它會造成雜亂的API。
    每個“著色器程序”由許多簡單的組件“著色器”組成,它們被鏈接在一起。目前有兩種常見的著色器類型,即頂點著色器和片段著色器。較新的硬件可能包含其他著色器類型,例如幾何著色器。

    頂點著色器

    我們的第一個著色器是VERTEX_SHADER,它必須計算每個要生成的頂點的頂點位置。通常,這是我們傳遞給GL的每個頂點的一個頂點,但是使用幾何著色器等可以創建更多的頂點。
    頂點著色器只需要做一件事,即生成一個gl_Position值,該值必須是vec4()類型。使用傳統的OpenGL(我們在這里使用的),通常使用內置變量“gl_Vertex”來計算gl_Position,該變量是一個vec4(),代表固定功能渲染管線生成的頂點。
    大多數OpenGL程序傾向于使用透視投影矩陣將笛卡爾模型的模型空間坐標轉換為屏幕的“視圖坐標”空間。傳統的OpenGL包括通過“平移”,“旋轉”,“縮放”等操作這些矩陣的函數。現代的OpenGL程序員需要自己計算矩陣(或者有一個庫可以幫助他們)。
    在這里,我們將使用OpenGLContext的內置矩陣計算,它將為我們設置“模型 - 視圖矩陣”作為簡單的透視變換。
    視圖坐標中的最終頂點位置是使用模型視圖矩陣和要轉換的頂點的簡單點積來計算的。main()函數使用類C的GLSL語法定義,不返回任何內容(void)。這里使用的每個變量都是(內置的)全局變量,所以我們不必聲明它們的數據類型。
    OpenGL.GL.shaders.compileShader函數編譯著色器并檢查是否有編譯錯誤。(使用glCreateShader,glShaderSource和glshaders.compileShader)。

            VERTEX_SHADER = shaders.compileShader("""#version 120
            void main() {
                gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
            }""", GL_VERTEX_SHADER)

    頂點著色器處理頂點后,它會經過許多固定功能過程,包括“裁剪”過程,該過程可能會將單個頂點轉換為多個頂點,以便僅將幾何圖形渲染到近剪裁的“前方”平面。
    因此,如果三角形“映入眼簾”,則GL將生成兩個頂點,這些頂點位于三角形與近剪裁平面相交的點上,并從最初的一個三角形創建三個三角形(所有剪裁計劃也是如此為平截頭體)。

    片段著色器

    固定功能操作將生成“片段”,這些片段可以被粗略地認為是“可能的像素”。它們可能代表一個子采樣插值,或者最終會隱藏在另一個像素后面的值(透支)。我們的渲染器會得到一個(大量的)碎片,每個碎片都會根據我們的頂點著色器生成的三角形頂點的面積(gl_Position值)計算出一個位置。
    片段著色器只需*做一件事,即生成一個gl_FragColor值,即確定片段應該是什么顏色。著色器還可以決定為不同的顏色緩沖區寫入不同的顏色,甚至改變片段的位置,但其主要工作僅僅是確定像素的顏色(vec4()值)。
    在我們的代碼中,我們為每個像素創建一個新的顏色,這是一個純綠色不透明(最后1個)值。我們將該值賦給(全局內置的)gl_FragColor值,我們完成了。

    FRAGMENT_SHADER = shaders.compileShader("""#version 120
            void main() {
                gl_FragColor = vec4( 0, 1, 0, 1 );
            }""", GL_FRAGMENT_SHADER)

    現在我們已經定義了著色器,我們需要將它們編譯成可應用于幾何圖形的視頻卡上的程序。shaders.compileProgram便捷功能執行以下操作:
    - 創建著色器“程序”(glCreateProgram)
    - 為每個提供的著色器*著色器附加到程序
    - 鏈接程序(glLinkProgram)
    - 驗證程序(glValidateProgram,glGetProgramiv)
    - 清理并返回著色器程序
    著色器程序是一個不透明的GLuint,用于在與GL交談時引用著色器。有了這些,我們已經創建好了一個OpenGL著色器,現在我們只需要給它一些東西去渲染。

            shaders.glUseProgram(self.shader)

    頂點緩沖數據對象Vertex Buffer Data Object(VBOs)

    現代OpenGL想要你將數據盡可能的加載到顯卡上。對于幾何信息,往往通過頂點緩沖對象(VBO)將信息加載到顯卡上。VBO是存儲在顯卡上靈活的數據存儲區域,具有數據流輸入輸出多樣策略。
    對我們來講,我們可以將VBO當作是是顯卡上的一片用于存儲拷貝來的頂點描述信息的空間。我們將使用Numpy數組來定義這些數據,這是處理大量數值型數組數據的合適的格式。
    現代的顯卡在處理格式為單個的頂點數據都被緊湊的打包進VBO的數據時表現最佳。因此,數組中的每條記錄需要渲染一個單個的頂點。由于我們的著色器只需要頂點坐標信息,我們將使用3 float點數據(注:不用python中的double,而是3個機器floating點數據)
    現代OpenGL只支持三角和點類型的幾何,因此最簡單的繪制方法(盡管不是最快的)是指定一系列有序的三角形的頂點。本例中我們創建一個三角形和一個用戶看起來是方形(實際上是兩個共享頂點的三角形)
    vbo.VBO類簡單的獲取一個數組類型的數據,并將其存入顯卡中。它也有各種標志位去控制更高級的特性,這些我們將在之后討論。

    self.vbo = vbo.VBO(
                array([
                    [ 0, 1, 0 ],
                    [ -1,-1, 0 ], 
                    [ 1,-1, 0 ], 
                    [ 2,-1, 0 ], 
                    [ 4,-1, 0 ], 
                    [ 4, 1, 0 ], 
                    [ 2,-1, 0 ], 
                    [ 4, 1, 0 ],
                    [ 2, 1, 0 ],
                ],'f') 
            )

    至此,我們完成了所有的應用初始化工作,我們編譯了shader,VBO也已經準備好用于繪制了。現在我們需要告訴OpenGL如何渲染我們的場景。context的Render()方法在所有OpenGL樣板設置完成之后被調用,且場景需要在模型空間中被渲染。OpenGLContext已經創建了一個默認的模型視圖矩陣,相機距離原點10個偏移的透視場景。它將場景清空為純白,并準備好接受渲染命令。

        def Render(self, mode):
            """Render the geometry for the scene"""

    渲染(Rendering)

    告訴OpenGL使用我們已經編譯好的著色器。在我們啟用自定義的shader之前,GL使用固定管線著色器(legacy)。

            shaders.glUseProgram(self.shader)

    現在我們通知OpenGL,我們要啟用VBO作為幾何數據源。有兩種VBO類型可以使用,一是幾何數據緩沖,一是索引數據緩存,這里使用的是幾何數據緩沖。

            try: 
                self.vbo.bind() 
                try:

    現在我們通知OpenGL去處理從頂點指針(指向VBO的地址)找到頂點(位置)數據。VBO就像是常規的數組數據一樣,存儲在外存而不是主存中。VBO對象實際上傳遞一個void指針給數組指針,該指針指向有效的VBO數組的0地址。

                    glEnableClientState(GL_VERTEX_ARRAY); 
                    glVertexPointerf( self.vbo

    )

    最終,我們告知OpenGL去繪制一些幾何體。這里我們
    通知OpenGL使用偏移從0到9的這些頂點去繪制一些三角形(因此,得到三個三角形)。glDrawArray函數總是從頂點緩存(vertex array)中“依次”繪制。我們之后將嘗試使用索引繪制函數。

    glDrawArrays(GL_TRIANGLES, 0, 9)

    在完成了幾何體的渲染之后,我們要清空OpenGL環境。我們要解綁VBO以便不使用VBO的代碼可以執行,此外還要解綁shader,以便使用固定管線著色器(legacy)的幾何體的渲染行為可以正常執行。

                finally:
                    self.vbo.unbind() 
                    glDisableClientState(GL_VERTEX_ARRAY); 
            finally:
                shaders.glUseProgram( 0 )

    我們需要將該代碼作為最頂層的腳本調用(不是被其他腳本import之后調用)。之前導入的TestingContext同樣也提供了合適的主循環函數供給我們調用。

    if __name__ == "__main__":
        TestContext.ContextMainLoop()

    運行程序,我們應該看到一個綠色的三角形和一個長方形顯示在黑色背景上,如圖所示:
    這里寫圖片描述
    術語:
    - frustum(截錐)

    視野范圍,也就是"相機"所能看到的那一部分世界空間,包含一個近裁平面和一個遠裁平面,以及左邊、右邊、頂部和底部的剪裁平面。
    

    這里寫圖片描述

    • GLSL
      OpenGL中定義的著色器語言有兩個級別,早期的著器語言是低級裝配語言,在這之后出現的GLSL是一個更高級一些的類C語言,本教程將使用GLSL語言。此外還有第三方語言比如CG,也可以編譯同樣的代碼給DirectX和OpenGL渲染器。
    • legacy(遺留)
      OpenGL是一個古老的標準,大量的傳統的API已經被OpenGL標準委員會棄用了。盡管大多數供應商仍支持舊的標準,但官方已經不支持使用舊的標準。這些遺留的API使用大量的全局狀態變量確定的單一的渲染模型。新的API更加靈活,但需要使用起來也更加復雜。

    譯者附:

    完整程序

    from OpenGLContext import testingcontext
    BaseContext = testingcontext.getInteractive()
    
    from OpenGL.GL import *
    
    from OpenGL.arrays import vbo
    from OpenGLContext.arrays import *
    from OpenGL.GL import shaders
    
    class TestContext( BaseContext ):   
    
        def OnInit( self ):
            VERTEX_SHADER = shaders.compileShader("""#version 120 
                void main() {
                 gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
                 }""", GL_VERTEX_SHADER)
            FRAGMENT_SHADER = shaders.compileShader("""#version 120 
                void main() { 
                gl_FragColor = vec4( 0, 1, 0, 1 ); 
                }""", GL_FRAGMENT_SHADER)
            self.shader = shaders.compileProgram(VERTEX_SHADER,FRAGMENT_SHADER)
            self.vbo = vbo.VBO(
                array([
                    [ 0, 1, 0 ],
                    [ -1,-1, 0 ], 
                    [ 1,-1, 0 ], 
                    [ 2,-1, 0 ], 
                    [ 4,-1, 0 ], 
                    [ 4, 1, 0 ], 
                    [ 2,-1, 0 ], 
                    [ 4, 1, 0 ],
                    [ 2, 1, 0 ],
                ],'f') 
            )
    
        def Render( self, mode): 
            """Render the geometry for the scene.""" 
            shaders.glUseProgram(self.shader) 
            try: 
                self.vbo.bind() 
                try:
                    glEnableClientState(GL_VERTEX_ARRAY); 
                    glVertexPointerf( self.vbo )
                    glDrawArrays(GL_TRIANGLES, 0, 9)
                finally:
                    self.vbo.unbind() 
                    glDisableClientState(GL_VERTEX_ARRAY); 
            finally:
                shaders.glUseProgram( 0 ) 
    if __name__ == "__main__":
        TestContext.ContextMainLoop()
    版權聲明:本文為v_xchen_v原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/v_xchen_v/article/details/80337352

    智能推薦

    PySpark初級教程——第一步大數據分析(附代碼實現)

    概述 數據正以前所未有的速度與日俱增 如何存儲、處理和使用這些數據來進行機器學習?spark正可以應對這些問題 了解Spark是什么,它是如何工作的,以及涉及的不同組件是什么 簡介 我們正在以前所未有的速度生成數據。老實說,我跟不上世界各地里產生的巨大數據量!我敢肯定你已經了解過當今時代數據的產量。McKinsey, Gartner, IBM,等公司都給出了他們公司的數據。 這里有一些令人難以置信...

    FastAPI 教程翻譯 - 用戶指南 2 - 第一步 Tutorial - User Guide - First Steps

    The simplest FastAPI file could look like this: 最簡單的 FastAPI 文件可能如下所示: Copy that to a file main.py. 將其復制到文件 main.py 中。 Run the live server: 運行實時服務器: Note 注意 The command uvicorn main:app refers to: 命令 ...

    php基礎教程 第一步 環境配置及helloworld

    PHP 是服務器端腳本語言。全稱為 Hypertext Preprocessor 為超文本預處理器。 據說php8不久后也要發布了,趁著8還沒有發布趕緊寫一個php5到php7(在基礎教程寫完后將寫php7新特性)的教程。PHP版本之間更新會增加新特性(別的語言也一樣),但更新之后的語言大多數情況下并不會給人有陌生的感覺,php版本更新后會在某一部分功能上會更改編寫方式等。 php7相對于php5...

    JavaScript開源圖表庫Highcharts入門第一步教程

    Highcharts是一款純JavaScript編寫的圖表庫,為你的Web網站、Web應用程序提供直觀、交互式圖表。當前支持折線、曲線、區域、區域曲線圖、柱形圖、條形圖、餅圖、散點圖、角度測量圖、區域排列圖、區域曲線排列圖、柱形排列圖、極坐標圖等幾十種圖表類型。 點擊下載Highcharts最新試用版 系統要求 Highcharts僅基于本機瀏覽器技術,不需要Flash或Java之類的客戶端插件。...

    win32 編程 第一步:編譯器 & HelloWorld

    win32 編程 即:windows 編程         1. 編譯器搭建   因為第一次進入win32 編程 無論代碼還是環境搭建 肯定會有一些問題 考慮到通用性 所以決定最好使用open source 這樣即使出現問題 也可以向google求助 最后決定使用MinGW 即: Minimalist GNU for Windows   ...

    猜你喜歡

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡