在Android中使用OpenGL ES進行開發第(一)節:概念先行


1、前期基礎是知識儲備
筆者計劃寫三篇文章來詳細分析OpenGL ES基礎的同時也是入門關鍵的三個點:android

①OpenGL ES是什麼?與OpenGL的關係是什麼?——概念部分編程

②使用OpenGL ES繪製2D/3D圖形的第一步:定義圖形;——運用部分框架

③使用OpenGL ES繪製出②步驟中定義好的圖形:——運用部分,難點所在編程語言

經過這三篇文章的分析,就像給萬丈高樓墊定了基石,萬丈高樓平地起,後面利用OpenGLES作各類效果,各類變換都是創建在這三步的圖形編程理解之上的。ide

 

話很少說正文開始函數

(1)什麼是OpenGL?佈局

原做者   硅谷圖形公司(SGI)性能

開發者   KhronosGroup網站

穩定版本   4.6(2017年7月31日 )ui

編程語言      C

操做系統      跨平臺

類型       API

網站       http://www.opengl.org

OpenGL(英語:Open Graphics Library,譯名:開放圖形庫或者「開放式圖形庫」)是用於渲染2D、3D矢量圖形的跨語言、跨平臺的應用程序編程接口(API)。這個接口由近350個不一樣的函數調用組成,用來從簡單的圖形比特繪製複雜的三維景象。OpenGL經常使用於CAD、虛擬實境、科學可視化程序和電子遊戲開發。

爲了增強它的多語言和多平臺特性,已經用不少語言開發了OpenGL的各類綁定和移植——Java、Python、Perl、VisualBasic等等。

(2)什麼是OpenGL ES?

原做者   KhronosGroup

開發者   KhronosGroup

穩定版本      3.1(2014年3月17日 )

編程語言      C

操做系統      跨平臺

系統平臺      跨平臺

類型       API

網站       www.khronos.org/opengles

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

OpenGL ES是從OpenGL裁剪定製而來的,去除了glBegin/glEnd,四邊形(GL_QUADS)、多邊形(GL_POLYGONS)等複雜圖元等許多非絕對必要的特性。

其實換句話說,因爲手機等終端因爲GPU、內存、性能等各方面的限制,不可能像電腦端那樣完美執行OpenGL,因此,Khronos集團就爲OpenGl提供了一個子集—OpenGl ES。

通過多年發展,如今主要有兩個版本,OpenGL ES 1.x針對固定管線硬件的,OpenGL ES 2.x針對可編程管線硬件。如今Android開發使用的靈活度和可定製化程度更高的OpenGL ES 2.0版本,入門門檻相對於以前的OpenGL ES 1.x更高。

(3)OpenGL ES 1.x和OpenGL ES 2.x的區別——說明爲何OpenGL ES 2.0開發難度提升

 

釋義—OpenGL ES2.0, you make me write everything?—OpenGL ES2.0,你要讓我本身實現全部事?

OpenGL ES版本內容變化有顯著的差別,1.x仍是fixed function pipeline(固定管線硬件),到了2.x就變成programmable pipeline(可編程管線硬件),也就是說,使用2.x的時候,儘管寫最簡單的程式(如基本做圖、三角形、矩形或動做translate、rotate、scale等),必定要寫shader(着色器/渲染器)才能運做,於是提升了入門的門檻。

OpenGL ES 1.x是以OpenGL1.5規格來制定,強調API使用硬體加速來實現;

OpenGL ES 2.x則是以OpenGL2.0來制定,強調使用可程式化3D繪圖管線,能夠產生shader和program object,藉由OpenGL ES Shading Language來寫vertex shader(頂點着色器)和fragment shader(片元着色器)。

 

這是OpenGL ES 1.x固定管線硬件的運做方式;(關注橙色部分)

 

這是OpenGL ES 2.x可編程管線硬件的運做方式;(關注橙色部分)

從上面兩幅圖的對比,咱們知道2.x跟1.x版的差別在於vertex shader(頂點着色器)是本來的 transform 和 lighting 的部分,fragment shader(片元着色器)則是對應到 texture、colour sum、fog、alpha test 等功能;也就是說,這些(橙色的部分)本來在fixed function pipeline 時會由系統來作的計算,現在在programmable pipeline 都要本身寫 shader程式來作計算了,因此掌握的難度有所提升。

2、上代碼,簡單使用OpenGL ES
PS:準備工做

咱們用的是Android Studio;

支持OpenGL ES 2.0或更高版本的Android設備。

 

前面,一直在說使用OpenGL ES2.0難度有所提升……這裏又說簡單使用,是否是矛盾了?真的,相信筆者,這裏說簡單使用,是由於咱們真的只是把使用框架創建起來,因此簡單。分四步走:

第一步:在 Manifest 配置文件中聲明使用 OpenGL ES2.0;

<!--0x00020000 表明使用 OpenGL ES 2.0 接口-->

<uses-featureandroid:glEsVersion="0x00020000" android:required="true"/>

第二步:爲 OpenGL ES 圖形建立一個 Activity;

使用 OpenGL ES 的Android 應用跟其它類型的應用主要的區別體如今 Activity 佈局內容上的差別。一般咱們會使用 TextView、Button等已經封裝好的控件。而若是使用 OpenGL ES 的咱們就得繼承GLSurfaceView 來本身寫子類實現了。

public class OpenGLSample01Activity extends AppCompatActivity {

GLSurfaceView mGLSurfaceView;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("OpenGLSample01");

// Create a GLSurfaceView instance and set it
// as the ContentView for this Activity.
mGLSurfaceView = new MyGLSurfaceView(this);
setContentView(mGLSurfaceView);
}
}
咱們自定義一個MyGLSurfaceView,得到實例以後,做爲參數傳入setContentView中做爲視圖。到此爲止,Activity建立完畢。

第三步:自定義一個 MyGLSurfaceView 對象,繼承自GLSurfaceView;

GLSurfaceView,看到這裏有沒有想起Android中View的孿生兄弟SurfaceView,專門用來處理須要頻繁刷新的頁面的SurfaceView,其實GLSurfaceView在OpEnGL中只是做爲View容器,用來存放圖形的,而且和Activity實現綁定。

class MyGLSurfaceView extends GLSurfaceView {

private final MyGLRenderer mRenderer;

public MyGLSurfaceView(Context context){
super(context);

// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2);

mRenderer = new MyGLRenderer();

// Set the Renderer for drawing on the GLSurfaceView
setRenderer(mRenderer);
// Set the RenderMode
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
}
從代碼咱們能夠看到,GLSurfaceView本身並不作太多和繪製圖形相關的任務。繪製對象的任務是由該 View 中配置的 GLSurfaceView.Renderer 所控制的。在代碼中,咱們設置了GL ES版本,並將GLSurfaceView和Render鏈接起來。RenderMode有兩種RENDERMODE_WHEN_DIRTY 和RENDERMODE_CONTINOUSLY,前者是懶惰渲染,須要手動調用glSurfeaceView.requestRender() 纔會進行更新,然後者則是不停渲染。

第四步:實現GLSurfaceView.Renderer接口,配置本身的渲染器;

在一個使用 OpenGL ES 的應用中,一定少不了 GLSurfaceView.Renderer 接口的實現。該接口會控制和其相關聯的GLSurfaceView 的繪製行爲和內容(即繪製的圖形和圖形的特效),Renderer這個類中有三個方法會被系統調用,因此須要實現下面三個方法:

onSurfaceCreated():在Surface被建立時回調,用來配置 View 的 OpenGL ES 環境,只會被回調一次;

onDrawFrame():在繪製每一幀的時候回調;

onSurfaceChanged():在每次Surface尺寸變化時回調,例如當設備的屏幕方向發生改變時。

下面是一個很是基本的 OpenGL ES 渲染器的實現,它僅僅在GLSurfaceView 中畫一個黑色的背景:

public class MyGLRenderer implements GLSurfaceView.Renderer {

public void onSurfaceCreated(GL10 unused, EGLConfig config) {
// Set the background frame color
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

public void onDrawFrame(GL10 unused) {
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}

public void onSurfaceChanged(GL10 unused, int width, int height) {
//利用glViewport()設置Screen space的大小,在onSurfaceChanged中回調
GLES20.glViewport(0, 0, width, height);
}
}
Render接口重寫的三個方法中調用的GLES20的API方法解析:

glClearColor()-設置清空屏幕用的顏色,接收四個參數分別是:紅色、綠色、藍色和透明度份量,0表示透明,1.0f相反;

glClear()-清空屏幕,清空屏幕後調用glClearColor()中設置的顏色填充屏幕;

glViewport()-設置視圖的尺寸,這就告訴了OpenGL能夠用來渲染surface的大小。

經過以上四步,咱們就作完了一個簡單可是頗爲完整的OpenGL ES的繪製流程,是否是如筆者以前所說的仍是比較簡單的:

①建立一個GlSurfaceView,綁定至Activity;

②爲這個GlSurfaceView設置渲染;

③在GlSurfaceView.renderer中繪製處理顯示數據;

每一步的職責和任務清晰。那麼爲何說頗爲完整,由於不涉及到具體的圖形的繪製和圖形特效的處理,也即沒有出現前文花大量筆墨闡述的shader着色器的相關運用,那麼shader着色器到底如何使用,圖形如何定義和繪製,咱們在接下來的文章裏接着分析。

相關文章
相關標籤/搜索