1. 程式人生 > >OpenGL ES總結(一)OpenGL 初識

OpenGL ES總結(一)OpenGL 初識

  • OpenGL是什麼?
  • OpenGL主要功能是什麼?
  • OpenGL ES是什麼?
  • Android中如何描述OpenGL ES版本
  • 對映座標繪製物件
  • 座標列表轉化為逆時針繪製順序
  • 小總結
  • OpenGL ES 3.1 Demo實踐

OpenGL是什麼?

OpenGL(全寫Open Graphics Library)是指定義了一個跨程式語言、跨平臺的程式設計介面規格的專業的圖形程式介面。它用於三維影象(二維的亦可),是一個功能強大,呼叫方便的底層圖形庫。

OpenGL™ 是行業領域中最為廣泛接納的 2D/3D 圖形 API,其自誕生至今已催生了各種計算機平臺及裝置上的數千優秀應用程式。OpenGL™ 是獨立於視窗作業系統或其它作業系統的,亦是網路透明的。在包含CAD、內容創作、能源、娛樂、遊戲開發、製造業、製藥業及虛擬現實等行業領域中,OpenGL™ 幫助程式設計師實現在 PC、工作站、超級計算機等硬體裝置上的高效能、極具衝擊力的高視覺表現力圖形處理軟體的開發。

OpenGL主要功能是什麼?

OpenGL是一個開放的三維圖形軟體包,它獨立於視窗系統和作業系統,以它為基礎開發的應用程式可以十分方便地在各種平臺間移植;OpenGL可以與Visual C++緊密介面,便於實現機械手的有關計算和圖形演算法,可保證演算法的正確性和可靠性;OpenGL使用簡便,效率高。它具有七大功能:

  • 1、建模:OpenGL圖形庫除了提供基本的點、線、多邊形的繪製函式外,還提供了複雜的三維物體(球、錐、多面體、茶壺等)以及複雜曲線和曲面繪製函式。
  • 2、變換:OpenGL圖形庫的變換包括基本變換和投影變換。基本變換有平移、旋轉、縮放、映象四種變換,投影變換有平行投影(又稱正射投影)和透視投 影兩種變換。其變換方法有利於減少演算法的執行時間,提高三維圖形的顯示速度。
  • 3、顏色模式設定:OpenGL顏色模式有兩種,即RGBA模式和顏色索引(Color Index)。
  • 4、光照和材質設定:OpenGL光有自發光(Emitted Light)、環境光(Ambient Light)、漫反射光(Diffuse Light)和高光(Specular Light)。材質是用光反射率來表示。場景(Scene)中物體最終反映到人眼的顏色是光的紅綠藍分量與材質紅綠藍分量的反射率相乘後形成的顏色。
  • 5、紋理對映(Texture Mapping)。利用OpenGL紋理對映功能可以十分逼真地表達物體表面細節。
  • 6、點陣圖顯示和圖象增強圖象功能除了基本的拷貝和畫素讀寫外,還提供融合(Blending)、抗鋸齒(反走樣)(Antialiasing)和霧(fog)的特殊圖象效果處理。以上三條可使被模擬物更具真實感,增強圖形顯示的效果。
  • 7、雙快取動畫(Double Buffering)雙快取即前臺快取和後臺快取,簡言之,後臺快取計算場景、生成畫面,前臺快取顯示後臺快取已畫好的畫面。

OpenGL ES是什麼?

OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三維圖形 API 的子集,針對手機、PDA和遊戲主機等嵌入式裝置而設計。該API由Khronos集團定義推廣,Khronos是一個圖形軟硬體行業協會,該協會主要關注圖形和多媒體方面的開放標準。

Android包括支援高效能2d和3d圖形與開放圖形庫(OpenGL®),具體來說,OpenGL ES API。OpenGL是一個跨平臺圖形API,用於指定一個標準為3 d圖形處理硬體的軟體介面。OpenGL ES的味道OpenGL規範用於嵌入式裝置。Android支援OpenGL ES API的幾個版本:

  • OpenGL ES 1.0和1.1 -這個API規範支援Android 1.0和更高版本。
  • OpenGL ES 2.0 -這個API規範支援Android 2.2(API級別8)和更高。
  • OpenGL ES 3.0 -這個API規範支援Android 4.3(API級別18)和更高。
  • OpenGL ES 3.1 -這個API規範支援Android 5.0(API級別21)和更高。

Android支援OpenGL通過其框架API和本地開發工具包(NDK)。

在Android框架有兩個基本類,讓你建立和操作圖形與OpenGL ES API:GLSurfaceView GLSurfaceView.Renderer。

GLSurfaceView

  • 這是一個檢視類,我們可以使用OpenGL繪製和操作物件API呼叫和SurfaceView是相似的函式。您可以使用這個類建立一個例項GLSurfaceView並add到你的Renderer(渲染器)。
public void setRenderer(GLSurfaceView.Renderer renderer)  
  • 起到連線OpenGL ES與Android 的View層次結構之間的橋樑作用。
  • 使得Open GL ES庫適應於Anndroid系統的Activity生命週期。
  • 使得選擇合適的Frame buffer畫素格式變得容易。
  • 建立和管理單獨繪圖執行緒以達到平滑動畫效果。
  • 提供了方便使用的除錯工具來跟蹤OpenGL ES函式呼叫以幫助檢查錯誤。

GLSurfaceView.Renderer

這個介面定義了在GLSurfaceView繪製圖形時所需的方法。既然是介面,那麼就必須有一個實現該介面的類。然後使用GLSurfaceView.setRenderer(這裡接收那個具體實類)方法,把這個實現類set到GLSurfaceView上。

GLSurfaceView.Renderer介面需要實現以下方法:

  • onSurfaceCreated():建立GLSurfaceView時回撥。使用這個方法來執行操作,只需要發生一次,如設定OpenGL環境引數或初始化OpenGL圖形物件。設定一些繪製時不常變化的引數,比如:背景色,是否開啟 z-buffer等。
  • onDrawFrame():每繪製一幀的時回撥。
  • onSurfaceChanged():GLSurfaceView幾何變化時回撥,包括GLSurfaceView大小的變化或裝置的螢幕變換。

Android中如何描述OpenGL ES版本?

AndroidManifest.xml中加入:
For OpenGL ES 2.0:

<!-- Tell the system this app requires OpenGL ES 2.0. -->
<uses-feature android:glEsVersion="0x00020000" android:required="true" />

For OpenGL ES 3.0:

<!-- Tell the system this app requires OpenGL ES 3.0. -->
<uses-feature android:glEsVersion="0x00030000" android:required="true" />

For OpenGL ES 3.1:

<!-- Tell the system this app requires OpenGL ES 3.1. -->
<uses-feature android:glEsVersion="0x00030001" android:required="true" />

對映座標繪製物件

OpenGL是假定一個正方形,統一系統座標,預設情況下,它是將這些看起來在非正方形的螢幕上,看起來像正方形。

這裡寫圖片描述

預設的OpenGL座標系(左)對映到一個典型的Android裝置螢幕(右)。

上面的圖顯示了(左邊)一個OpenGL的統一座標系統,和如何將這些座標對映到(右邊)一個典型的橫向裝置螢幕。為了解決這個問題,我們可以應用OpenGL正確的比例下通過投影模式和相機檢視座標轉換你的圖形物件。

為了應用投影和相機檢視,我們建立一個投影矩陣和一個相機檢視矩陣並將它們應用於OpenGL渲染管道中。投影矩陣重新計算你的圖形的座標,使他們正確地對映到Android裝置的螢幕。相機檢視矩陣建立一個轉換,它將從一個特定的位置顯示物件。

投影(Projection)和OpenGL ES 1.0相機檢視( Camera View )

投影矩陣——建立一個投影矩陣使用裝置螢幕以重新計算物件的幾何座標所以他們用正確的比例。下面的示例程式碼演示瞭如何修改onSurfaceChanged GLSurfaceView()方法。渲染器實現來建立一個基於螢幕的長寬比和投影矩陣應用於OpenGL渲染環境。

public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);

    // make adjustments for screen ratio
    float ratio = (float) width / height;
    gl.glMatrixMode(GL10.GL_PROJECTION);        // set matrix to projection mode
    gl.glLoadIdentity();                        // reset the matrix to its default state
    gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);  // apply the projection matrix
}

相機變換矩陣——一旦你使用投影矩陣調整座標系統,我們還必須新增一個相機檢視。下面的示例程式碼顯示瞭如何修改onDrawFrame GLSurfaceView()方法。渲染器實現應用模型檢視,並使用GLU.gluLookAt()實用程式來建立一個模擬攝像機觀察變換位置。

public void onDrawFrame(GL10 gl) {
    ...
    // Set GL_MODELVIEW transformation mode
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();                      // reset the matrix to its default state

    // When using GL_MODELVIEW, you must set the camera view
    GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    ...
}

投影和OpenGL ES 2.0和更高版本的相機檢視

ES 2.0和3.0 api,應用投影和相機檢視首先要新增一個矩陣圖形的頂點著色器(Shader)物件成員。添加了這個矩陣成員,我們可以生成和應用投影和相機觀察矩陣物件。

頂點著色器新增矩陣——為檢視建立一個變數投影矩陣,包括乘數著色器的位置。在下面的例子中頂點著色器程式碼,包括uMVPMatrix成員允許您應用投影和相機觀測矩陣的座標物件。

private final String vertexShaderCode =

    // This matrix member variable provides a hook to manipulate
    // the coordinates of objects that use this vertex shader.
    "uniform mat4 uMVPMatrix;   \n" +

    "attribute vec4 vPosition;  \n" +
    "void main(){               \n" +
    // The matrix must be included as part of gl_Position
    // Note that the uMVPMatrix factor *must be first* in order
    // for the matrix multiplication product to be correct.
    " gl_Position = uMVPMatrix * vPosition; \n" +

    "}  \n";

訪問著色矩陣之後,建立一個鉤在你的頂點著色器應用投影和相機檢視中,您可以訪問該變數應用投影和相機觀測矩陣。下面的程式碼演示如何修改onSurfaceCreated GLSurfaceView()方法。渲染器實現訪問上面的頂點著色器中定義的矩陣變數。

public void onSurfaceCreated(GL10 unused, EGLConfig config) {
    ...
    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    ...
}

建立投影和相機觀察矩陣——生成投影矩陣和檢視應用的圖形物件。下面的示例程式碼顯示瞭如何修改onSurfaceCreated()和onSurfaceChanged GLSurfaceView()方法。渲染器實現建立相機檢視矩陣和投影矩陣基於裝置的螢幕寬高比。

public void onSurfaceCreated(GL10 unused, EGLConfig config) {
    ...
    // Create a camera view matrix
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
}

public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;

    // create a projection matrix from device screen geometry
    Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

應用投影和相機觀察矩陣——應用投影和相機檢視的轉換,將矩陣的相乘,然後設定在頂點著色器中。下面的程式碼顯示瞭如何修改onDrawFrame GLSurfaceView()方法。渲染器實現結合投影矩陣和相機檢視中建立上面的程式碼,然後把它應用到由OpenGL渲染的圖形物件。

public void onDrawFrame(GL10 unused) {
    ...
    // Combine the projection and camera view matrices
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

    // Apply the combined projection and camera view transformations
    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    // Draw objects
    ...
}

在OpenGL,一個形狀是一個表面由三個或更多的點在三維空間中定義的。一組三個或更多三維點(稱為頂點在OpenGL)有正面和背面。你怎麼知道哪面是正面和背面?答案是 winding,或者簡單的說,你定義點的方向。

這裡寫圖片描述

座標列表轉化為逆時針繪製順序

在這個例子中,三角形的點是通過一定的順序定義的,以致它們是通過逆時針方向繪製的。這些座標定義的順序就是環繞方向。預設情況下,在OpenGL中,我們正對的方向是逆時針畫的方向。上圖所示的三角形定義,我們看到就是正面,另一邊是背面。

為什麼我們要知道,我們面對的是不是正面?原因是:在處理OpenGL的常用特性時,有一個叫Face culling的環境因素,Face culling是OpenGL中一個可以參考的環境,它可以讓你在渲染到pipeline的過程中忽略背面(不計算或繪製),節省時間,記憶體和處理週期。

// enable face culling feature
gl.glEnable(GL10.GL_CULL_FACE);
// specify which faces to not draw
gl.glCullFace(GL10.GL_BACK);

如果我們嘗試使用Face culling特性,但又不知道它的形狀是正面和背面,我們的OpenGL圖形看起來有點怪,或者有時根本不顯示。所以,總是定義我們的OpenGL圖形的座標逆時針順序。

以上小總結:

  • OpenGL 繪製的都是圖形,包括形狀和填充,基本形狀是三角形。
  • 每個形狀都有頂點,Vertix,頂點的序列就是一個圖形。
  • 圖形有正反面,如果我們看向一個圖形,它的頂點序列是逆時針方向,那我們看到的就是正面。
  • Shader,著色器,用來描述如何繪製(渲染),GLSL 是 OpenGL 的程式語言,全稱就叫 OpenGL - -Shader Language。OpenGL 渲染需要兩種 shader,vertex 和 fragment。
  • Vertex shader,控制頂點的繪製,指定座標、變換等。
  • Fragment shader,控制形狀內區域渲染,紋理填充內容。

OpenGL ES 3.1 Demo實踐

效果圖:


這裡寫圖片描述

這裡寫圖片描述

MyGLSurfaceView.java
這裡寫圖片描述
這裡寫圖片描述

Renderer
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

Square
這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述

Triangle
這裡寫圖片描述
這裡寫圖片描述這裡寫圖片描述

第一時間獲得部落格更新提醒,以及更多android乾貨,原始碼分析,歡迎關注我的微信公眾號,掃一掃下方二維碼或者長按識別二維碼,即可關注。

這裡寫圖片描述
如果你覺得好,隨手點贊,也是對筆者的肯定,也可以分享此公眾號給你更多的人,原創不易

相關推薦

OpenGL ES總結OpenGL 初識

OpenGL是什麼? OpenGL主要功能是什麼? OpenGL ES是什麼? Android中如何描述OpenGL ES版本 對映座標繪製物件 座標列表轉化為逆時針繪製順序 小總結 OpenGL ES 3.1 Demo實踐 OpenGL是什麼? O

OpenGL ES總結OpenGL ES中EGL

Agenda: EGL是什麼? EGL資料型別 EGL在Android中應用 EGL的工作流程 GLSurfaceView與EGL區別 簡單Demo EGL是什麼? EGL? is an interface between Khronos rend

OpenGL ES總結OpenGL 渲染視訊畫面

前一篇介紹是渲染一張圖片,今天是在MediaPlayer播放過程中,渲染視訊,看下Agenda: 與渲染圖片的區別 建立SurfaceTexture 設定shader(著色器) 建立紋理座標 UV座標介紹 UV紋理座標設定與貼圖規則是什麼? 視訊播放

OpenGL 使用總結

OpenGL 使用總結 一 OpenGL是一個客戶-伺服器端模型執行的。一個應用程式(客戶端)發出OpenGL指令流,然後由OpenGL的具體實現(伺服器端)來解釋執行。客戶端和伺服器端可能是通過網路連線,也可以在同一機器上。如果在同一個機器上,就會產生一個CPU-GPU邊界的問題,呼叫O

OpenGL ES 光照

Opengl es 基本光照 Opengl es 中將光照分成了3種組成元素(3個通道),環境光、散射光以及鏡面光。 環境光(Ambient): 物體周圍的光線,從四面八方照射到物體上,全方位360度都是均勻的光,不依賴於光源位置,而且沒有方向性。環境光不但入射均勻,

OpenGL學習總結

OpenGL基礎 一、OpenGL是一個狀態機 OpenGL本身是一個巨大的狀態機,所以程式設計的根本目的使用一些列操作和變數來改變OpenGL的工作狀態,例如:要繪製一個三角形的時候,我們先要告訴它接下來將要繪製三角形,使其切換狀態,然後再將要繪製

OpenGL在MFC中的使用總結——基本框架

palette 接受 white 要求 無效 結構 del 一次 是你 項目中要畫3D顯示的模型,於是要用到OpenGL,加上是在MFC中,並且是在MFC中的ActiveX中使用。再並且鑒於他們程序主框架的設定。常規的方法還不一定能實現。所以還是查過不少資料,在此一一總

OpenGL ES 光照

鏡面光(Specular): 當光滑物體表面被照射時會有方向很集中的反射光鏡面光的最終強度依賴於入射光、觀察者的位置 鏡面光的計算模型比前面的兩種光都要複雜一些,具體公式如下。 鏡面光照射結果=材質的反射係數×鏡面光強度×max(0,(cos(半向量與法向量的夾角)) ^粗糙度

OpenGL ES 光照

散射光(Diffuse): 從物體表面向全方位360度均勻反射的光,反射後的散射光在各個方向是均勻的,但反射光的反射強度與入射光的強度以及入射角度密切相關。垂直地照射到物體表面時比斜照時要亮。 散射光具體計算公式: 其中設光照入射角為α. 散射光照射結果=材質的反射係數×散射

OpenGL學習筆記概念瞭解

  OpenGL一般被認為是一種API(Aplication Programming Interface),包含了一系列可以操作圖形、影象的函式。但實際上它是一種規範,它嚴格規定了每個函式該如何執行以及它們的輸出值。   OpenGL就是一個大狀態機,它通過一些狀態設定的函

新版OpenGL學習入門——初始化視窗

主要用來記錄一下學習程式碼,每次新建一個專案還要配置太麻煩啦 配置網址:https://blog.csdn.net/qq_19003345/article/details/76098781  學習的是可編輯管線,不過順便也配置了一下舊版本的,這樣可以偶爾執行一下別人的程式碼 題

Caffe學習總結——初識caffe

深度學習在當前情況下可以用一個字來形容“火”,目前專案中使用到了常用的機器學習演算法,在使用過程中發現影象的特徵提取成為識別的瓶頸,無意中瞭解到caffe,可以很好的解決特徵提取的問題。於是想嘗試一下caffe的威力。初識caffe,就習慣性了想了解下作者,發現

Android OpenGL ES 開發— 繪製三角形

        在前一篇部落格我們知道了Android中OpenGL ES是什麼,然後知道了怎麼搭建一個OpenGL ES的執行環境,現在我們就來開始繪製我們自己想要的圖形了(繪製圖片會在後面講解,因為繪製圖形是繪製圖片的基礎),我們最先開始繪製一個三角形

OpenGL基礎圖形程式設計OpenGL與3D圖形世界

一、OpenGL與3D圖形世界1.1、OpenGL使人們進入三維圖形世界  我們生活在一個充滿三維物體的三維世界中,為了使計算機能精確地再現這些物體,我們必須能在三維空間描繪這些物體。我們又生活在一個充滿資訊的世界中,能否儘快地理解並運用這些資訊將直接影響事業的成敗,所以我

OpenGL 學習筆記——開始以及OPENGL環境配置

         今天,開始學習OPENGL,以後會定期地釋出部落格,鼓勵自己學習,以及督促自己學習。浪費了許久的時間,終於覺得有必要學習一些東西了。希望還不會太晚吧。好了話不多說,首先開始OpenGL 的環境配置吧。 一、安裝GLUT工具包(可選) GLUT並不是Open

[置頂] 自己動手實現OpenGL之glViewPort

直接上程式碼。 public static void glViewport( int x, int y, int width, int height ) { int surfaceHeig

java_web項目開發經驗總結

從數據 簡單 處理 開發 事務 傳輸 記錄 承載 基礎上   web項目就像一個動態的記事本,功能很強大,你最初的項目功能調研越給力,項目所能發揮的作用也就越給力。這是因為web網絡的強聯系性,大家都可以通過訪問到自己想要訪問的頁面,頁面裏既可以承載信息,也可以承載做事情的

文檔總結——文檔的概述

理解 需要 軟件需求 是否 研究 strong 開發項目 問題 項目開發 寫完文檔後,本來想寫一篇具體的文檔的總結的,後來看大家都寫的具體文檔總結,於是我就想:我還是寫一些跟大家不一樣的東西吧。 所以,我就說說我對各個文檔的宏觀理解吧。

salesforce零基礎學習七十二項目中的零碎知識點小總結

gin 不同 grant dmi ima -m ron 角色 com 項目終於告一段落,雖然比較苦逼,不過也學到了好多知識,總結一下,以後當作參考。 一.visualforce標簽中使用html相關的屬性使用 曾經看文檔沒有看得仔細,導致開發的時候走了一些彎路。還好得到

操作系統基礎知識總結

一個 快速 會有 處理死鎖 b2c fcm 死鎖 空間 存儲系統 1. 進程和線程的區別 進程 進程,即正在運行的程序,程序從硬盤載入到內存就變成進程。進程是資源的擁有者,每個進程都擁有著自己的內存空間與多個線程。 線程 線程是指令的執行者,是計算機執行指令的基本單元,一個