我的視頻課程(基礎):《(NDK)FFmpeg打造Android萬能音頻播放器》
我的視頻課程(進階):《(NDK)FFmpeg打造Android視頻播放器》
我的視頻課程(編碼直播推流):《Android視頻編碼和直播推流》
對於Opengl/sl/cv/...系列相信大家也不陌生,我在前面博客也介紹了OpenSL ES的一些知識和使用方法,讓我們對OpenSL ES有了一定的瞭解。從今天開始我將給大家帶來一系列的Android中OpenGL ES的使用方法(主要是基於2D平面圖形的)。
一、OpenGL ES是什麼?
我總結的就是:OpenGL ES 是一個嵌入式的(2D/3D)圖形處理庫。詳細請見百度百科。
二、OpenGL ES能做什麼?
就拿我們的手機顯示系統來說,我們的屏幕顯示一個UI界面,其繪製就是OpenGL ES來完成的。由CPU計算每個控件的繪製座標和顏色等,當這些計算完了後就交給OpenGL ES來調用GPU(顯卡),通過GLSL(着色器程序)來繪製畫面,這樣就把我們的UI界面繪製出來了。其他的還有:遊戲、圖片濾鏡、視頻等都可以用OpenGL來處理。
三、Android中的OpenGL ES
在Android中使用OpenGL ES有2中方法:
1、一個是在Java層調用OpenGL ES庫;
2、另一個就是在C/C++層調用OpenGL ES庫。
不過這2中方法調用OpenGL ES 的方式和過程都基本一致,所以博客主要以Java方式來講解OpenGL ES的使用,後面如果有需要可能會講一下C/C++的實現方法。
四、Android中使用OpenGL ES的方式(先作介紹,後續都會講解,概念不懂可以暫時忽略)
在Android中使用OpenGL ES的方式也有2中:
1、自定義類直接繼承GLSurfaceView,然後我們重點就主要寫Render方法就行。
2、自己搭建EGL(是OpenGL ES和本地窗口系統的接口,不同平臺上EGL配置是不一樣的,而OpenGL的調用方式是一致的,就是說:OpenGL跨平臺就是依賴於EGL接口)環境,然後開啓自己的EGL線程,後續使用和繼承GLSurfaceView基本是一致的。
注意:OpenGL ES整個其實就是一個大的狀態機,我們通過改變其狀態(調用相關的API)就能控制其後續的渲染操作。
五、Android中OpenGL ES的初體驗(v2.0)
1、自定義類繼承GLSurfaceView
2、實現接口GLSurfaceView.Renderer,其有3個實現方法,分別是:
2.1:void onSurfaceCreated(GL10 gl, EGLConfig config); 用於我們的Surface創建時初始化一些設置。
2.2:void onSurfaceChanged(GL10 gl, int width, int height); 用於我們的Surface大小發生改變時來更改我們自己的繪製大小。
2.3:void onDrawFrame(GL10 gl); 用於我們實際繪製操作。
注意:GLSurfaceView.Renderer的方法都是在自己的EGL線程中實現的,超出這個線程繪製是不起作用的
六、實例-把我們的窗口繪製成紅色(rgb:f00,在OpenGL中f就是1,0也是0,所以紅色就是:rgb:100)
1、自定義WlGLSurfaceView類繼承GLSurfaceView類:
package com.ywl5320.opengldemo;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
public class WlGLSurfaceView extends GLSurfaceView{
public WlGLSurfaceView(Context context) {
this(context, null);
}
public WlGLSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
setEGLContextClientVersion(2);//設置opengl es版本爲2.0
setRenderer(new WlRender());//爲glsurfaceview設置render
}
}
繼承GLSurfaceView,我們只是在構造函數中設置了當前opengl es 使用的版本,這裏是設置的2.0版本(setEGLContextClientVersion(2)),然後把我們的Render設置給當前自定義的WlGLSurfaceView(setRenderer(new WlRender())),接下來我們就來實現WlRender。
2、實現GLSurfaceView.Render接口:
package com.ywl5320.opengldemo;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class WlRender implements GLSurfaceView.Renderer{
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);//用紅色來清屏(屏幕將變成紅色)
}
}
這裏需要實現onSurfaceCreated、onSurfaceChanged、onDrawFrame三個方法。
2.1、在方法onSurfaceCreated中是做初始化工作,這裏我們暫時用不到。
2.2、在方法onSurfaceChanged中我們調研OpenGL ES的方法:GLES20.glViewport(0, 0, width, height);設置OpenGL ES渲染窗口的大小,前2個參數分別是起點x和y的值,第三個參數是窗口寬(width),第四個參數是窗口高(height)這裏回調方法裏面的寬高就是當前WlGLSurfaceView的寬高。
2.3、在方法onDrawFrame中就是我們需要繪製的操作了,這裏執行了兩個操作:第一個是顏色緩衝清屏(GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)),除了顏色緩存清屏以外,常用的還有深度緩衝清屏(GLES20.GL_DEPTH_BUFFER_BIT),不過這個主要用在3d渲染裏面,2d渲染不會用到;第二個是用指定的顏色來清屏(GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);),效果就是用什麼顏色後,屏幕就會變成什麼顏色,顏色格式是 rgba的,每個分量取值範圍都是(0~1),比如這裏的紅色就是:(1.0f, 0.0f, 0.0f, 1.0f)。
3、Activity中佈局調用:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.ywl5320.opengldemo.WlGLSurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
因爲我們在WlGLSurfaceView裏面就進行了繪製,所在這裏直接在佈局中加入WlGLSurfaceView就行,然後運行程序就會出現效果的。
4、運行結果:
好了,OpenGL ES第一次接觸就到這裏,在後面博客會慢慢深入學習的,本實例下載地址:
GitHub:Android-OpenGL-ES