Android OPENGL 第一天:實(shí)現(xiàn)基本的圖形繪制

因?yàn)轫?xiàng)目的一個(gè)將GLSurface的界面效果導(dǎo)出成為MP4文件,我做的很難看,導(dǎo)出的視頻很不理想,然后我就只能自學(xué)一下

openGL是一個(gè)跨平臺(tái)的東西,不管安卓還是ios都可以用,他也是一些游戲繪制的基礎(chǔ),openGL也是圖形學(xué)的研究工具,今天我就帶讀者一起搞一下openGL,本人剛剛大學(xué)畢業(yè),對(duì)圖形學(xué)這個(gè)東西不熟,剛開始寫的不對(duì)的,別噴我!

openGL具體是什么,原理是什么,我就用白話說一下,這樣子方便理解:

opengl其實(shí)是一個(gè)開放的圖形庫(kù)接口,可以適用很多平臺(tái),Windows,macos,Android,ios,Linux,因?yàn)椴还苣闶鞘裁聪到y(tǒng),你肯定要使用到3D圖形,所以這個(gè)東西必不可少。當(dāng)然,你想學(xué)會(huì)這個(gè)玩意,還需要一定的數(shù)學(xué)功底還有幾何的數(shù)學(xué)基礎(chǔ)。我就舉個(gè)很簡(jiǎn)單的例子:

假如你想實(shí)現(xiàn)一個(gè)三角形的圖形,在安卓上,先跟著我的思路來:

剛開始你肯定要新建一個(gè)GLSurface的view用來顯示東西,OK:

GLSurfaceView view =new GLSurfaceView(this);

但是你創(chuàng)建以后,那怎么讓他顯示你想要的東西呢?你看一下gl繼承啥?

public class GLSurfaceView? extends SurfaceView implements Callback2 {....}

????他繼承是SurfaceView ,大家可以想一下,為什么要繼承這個(gè),而不是繼承其他的,必須View或者ViewGroup,GL他是一個(gè)圖形接口,讓GLSurfaceview去展示對(duì)應(yīng)的圖形,就打個(gè)比方,你玩王者榮耀的時(shí)候,如果人物一卡一卡的,你是不是很難受,然后安卓的自己的view的刷新頻率是跟不上的,會(huì)炸掉,平常手機(jī)拍照,就不會(huì)很卡,但是手機(jī)拍照是拿什么現(xiàn)實(shí)的呢?是surfaceview,為什么不卡呢?因?yàn)槟闩恼盏臅r(shí)候,你要不斷刷新你當(dāng)前攝像頭的畫面,所以你必須得提高你的刷新頻率,讓人的肉眼看不到刷新的效果,所以GL繼承Surfaceview是一個(gè)不錯(cuò)的選擇,所以GL不僅僅是作為一個(gè)圖形庫(kù)接口,也可以用來播放視頻,錄像等高頻率刷新的操作。

????然后我們繼續(xù):我們創(chuàng)建了一個(gè)GL,那怎么樣才可以讓他渲染出來東西,你有一張紙了,那是不是得有一個(gè)畫筆,這個(gè)畫筆就是渲染器(Renderer)

public interface Renderer {

????void onSurfaceCreated(GL10 var1, EGLConfig var2);

? ? void onSurfaceChanged(GL10 var1, int var2, int var3);

? ? void onDrawFrame(GL10 var1);

}

????他是一個(gè)GLSurfaceView的內(nèi)部接口,包括了界面初始化(void onSurfaceCreated(GL10 var1, EGLConfig var2)),視圖窗體改變(void onSurfaceChanged(GL10 var1, int var2, int var3)),視圖繪制(?void onDrawFrame(GL10 var1))等三個(gè)接口回調(diào),之前提到的快頻率的刷新就是在onDrawFrame里面進(jìn)行刷新的

? ? 當(dāng)你有一個(gè)畫筆,你畫畫是不是得做好采樣點(diǎn),也就是所謂的坐標(biāo)系,因?yàn)樵诎沧渴謾C(jī)里面需要有一個(gè)坐標(biāo)系規(guī)定每個(gè)圖形的顯示位置,包括大小,旋轉(zhuǎn)角度以及方向,都是由坐標(biāo)系進(jìn)行決定的。但是openGL 的坐標(biāo)系是什么樣子的呢?

? ? 我們一般畫二維的,還是三維的,都是用笛卡爾坐標(biāo)系,但是你得有一個(gè)原點(diǎn)(0,0,0),然后在根據(jù)原點(diǎn)去定圖形的位置方向等。

????坐標(biāo)原點(diǎn)默認(rèn)在屏幕的中間,即(width/2,height/2)位置上,z軸是從屏幕"內(nèi)"指向屏幕外,而且還要注意原點(diǎn)和x,y軸平面是在屏幕的"表面",有引號(hào),這個(gè)"表面"剛好是人看不到的面,所以如果你要畫一條線,線端點(diǎn)(1,0,0),(0,1,0),直接畫到屏幕上,將看不到顯示,怎么辦?很簡(jiǎn)單,這個(gè)坐標(biāo)系是三維空間的,那么就將坐標(biāo)系沿Z軸的負(fù)軸方向移動(dòng)一點(diǎn),將X,Y平面稍微向屏幕內(nèi)部移動(dòng)一點(diǎn),就能夠看到直線了,想象一下在三維空間中,將坐標(biāo)系往屏幕里面推一下,那么x,y軸形成的平面就在屏幕里面了,在它上面的直線就可以看見了。

? ? 這個(gè)坐標(biāo)系和安卓的傳統(tǒng)坐標(biāo)系是不是有一點(diǎn)不一樣,因?yàn)镚L是三維的成像模型,所以Z軸是必須要存在的,不過你可能用不到,但是也必須得要!那你有一個(gè)坐標(biāo)系了,那你是不是得有一個(gè)視角(gluLookAt),這個(gè)將決定你對(duì)于物體的觀察成像是什么樣子的?不過一般是從Z軸看里面,我一般設(shè)置為:

GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0,1,0);

然后還有規(guī)定的顯示區(qū)域大小:

GL10#glViewport(0, 0, width, height)

一般是將屏幕的寬高做為界面規(guī)定區(qū)域的寬高

作為頻繁刷新的view,那你還得有一個(gè)清屏色,一般是黑色,然后GL提供了一個(gè)方法:

GL10#glColor4f(0f, 0f, 0f, 1f);

參數(shù)分別為R,G,B和Alpha

基本的參數(shù)都設(shè)置好了,那我們就開始畫三角形

三角形要有三個(gè)點(diǎn),三個(gè)點(diǎn)的坐標(biāo)(X,Y),從坐標(biāo)軸上拾取,我們可以初步定為

float[] coords = {

????????0f,0.5f,0f,

? ? ? ? -0.5f,-0.5f,0f,

? ? ? ? 0.5f,-0.5f,0f,

};

那你肯定好奇了,為什么都寫一起了,不分開寫,我先不說,我們繼續(xù),你寫好三個(gè)點(diǎn)的坐標(biāo)以后,然后我們就把他畫出來,問題是咋告訴計(jì)算機(jī),我們要的是一個(gè)三角形呢?GL給我們提供了內(nèi)置的參數(shù):

GL10#glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

大家好奇了,這三個(gè)參數(shù)是什么意思呢?第一個(gè)還好說,是繪制一個(gè)三角形的參數(shù),第二個(gè)和第三個(gè)呢?第二個(gè)參數(shù)0是告訴計(jì)算機(jī),從第0個(gè)點(diǎn)開始繪制,第0個(gè)點(diǎn)是什么呢?看上面的數(shù)組,0,0.5,0,這就是第一個(gè)點(diǎn),那為什么是三個(gè)數(shù)字呢?因?yàn)镚L的坐標(biāo)系有X,Y,Z啊,所以確定一個(gè)點(diǎn)需要3個(gè)坐標(biāo)系以前確認(rèn)啊,所以得有三個(gè)點(diǎn),那第1個(gè)和第2個(gè)點(diǎn)大家都知道是多少了吧!那就直接傳入到方法參數(shù)里面,然后畫出來就好了,顯示的效果我截個(gè)屏:


那你好奇了,為什么這個(gè)三角形是紅色的呢?難道GL自己給他著色了嗎?不對(duì)的,這個(gè)是我自己設(shè)置的,怎么設(shè)置呢?上代碼:

GL10#glColor4f(1f, 0f, 0f, 1f)

這個(gè)是設(shè)置圖形的顏色的,R,G,B,Alpha,R是1 就是紅色了,其他的都是0,所以這樣子就好理解了,那假如我畫了兩個(gè)圖形呢,那我咋分開繪制不同的顏色呢?我明天再更新?。?!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容