Android基于OpenGL在GLSurfaceView上繪制三角形及使用投影和相機(jī)視圖方法示例
本文實(shí)例講述了Android基于OpenGL在GLSurfaceView上繪制三角形及使用投影和相機(jī)視圖方法。分享給大家供大家參考,具體如下:
定義三角形
OpenGL 允許我們使用三維坐標(biāo)來定義物體。在繪制三角形前,我們需要定義它各個(gè)點(diǎn)的坐標(biāo)。我們一般使用數(shù)組來存儲(chǔ)各個(gè)頂點(diǎn)的坐標(biāo)。
OpenGL ES 默認(rèn) [0,0,0] (X,Y,Z) 在GLSurfaceView的中心,[1,1,0]在右上角,[-1,-1,0]在左下角。
繪制三角形
在繪制三角形之前,我們必須告訴OpenGL我們正在使用頂點(diǎn)數(shù)組。然后我們才使用繪制函數(shù)畫出三角形。
實(shí)驗(yàn)步驟:
1. 添加新的類Triangle
代碼如下:
public class Triangle { public Triangle() { float triangleCoords[] = { // X, Y, Z 這是一個(gè)等邊三角形 -0.5f, -0.25f, 0, 0.5f, -0.25f, 0, 0.0f, 0.559016994f, 0 }; // 初始化三角形的頂點(diǎn)緩存 ByteBuffer vbb = ByteBuffer.allocateDirect( // (# of coordinate values * 4 bytes per float) triangleCoords.length * 4); vbb.order(ByteOrder.nativeOrder());// 使用設(shè)備硬件本身的字節(jié)序 triangleVB = vbb.asFloatBuffer(); // 從ByteBuffer中創(chuàng)建一個(gè)浮點(diǎn)緩存 triangleVB.put(triangleCoords); // 向浮點(diǎn)緩存中添加頂點(diǎn)坐標(biāo) triangleVB.position(0); // 使緩存讀第一個(gè)坐標(biāo) } public void draw(GL10 gl) { gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f); //設(shè)置當(dāng)前顏色 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);//設(shè)置頂點(diǎn) gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);//繪制三角形 } private FloatBuffer triangleVB; }
2. 在myGLRenderer類中添加成員privateTriangle mTriangle并在構(gòu)造函數(shù)中初始化。
代碼如下:
public myGLRenderer() { mTriangle = new Triangle(); }
3. 在myGLRenderer類的onSurfaceCreated()函數(shù)最后添加glEnableClientState()方法來啟用頂點(diǎn)數(shù)組。
代碼如下:
@Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); }
4. 在myGLRenderer類的onDrawFrame()函數(shù)最后添加三角形繪制方法。
代碼如下:
@Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); mTriangle.draw(gl); }
這樣,我們便完成了一個(gè)平面三角形的繪制。但我們發(fā)現(xiàn)這個(gè)三角形并不像我們定義的那樣是一個(gè)等邊三角形,這是由于OpenGL總假設(shè)我們的屏幕是一個(gè)正方形,這樣在繪制的時(shí)候最終圖形會(huì)隨著屏幕長(zhǎng)寬比例的不同而被拉伸。為了得到正確的顯示,我們需要將圖形投影到正確的位置。這一功能我們?cè)谙乱还?jié)進(jìn)行實(shí)現(xiàn)。
Android設(shè)備屏幕通常不是正方形的,而OpenGL總是默認(rèn)地將正方形坐標(biāo)系投影到這一設(shè)備上,這就導(dǎo)致圖形無法按真實(shí)比例顯示。要解決這一問題,我們可以使用OpenGL 的投影模式和相機(jī)視圖將圖形的坐標(biāo)進(jìn)行轉(zhuǎn)換以適應(yīng)不同的設(shè)備顯示。
實(shí)驗(yàn)步驟:
1. 修改myGLRenderer類的onSurfaceCreated()函數(shù)來啟用GL10.GL_PROJECTION模式,計(jì)算屏幕的長(zhǎng)寬比并使用這一比例來轉(zhuǎn)換物體的坐標(biāo)。
代碼如下:
@Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub gl.glViewport(0, 0, width, height); float ratio = (float) width / height; gl.glMatrixMode(GL10.GL_PROJECTION); // 設(shè)置當(dāng)前矩陣為投影矩陣 gl.glLoadIdentity(); // 重置矩陣為初始值 gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // 根據(jù)長(zhǎng)寬比設(shè)置投影矩陣 }
2. 修改myGLRenderer的onDrawFrame()方法,啟用MODELVIEW模式,并使用GLU.gluLookAt()來設(shè)置視點(diǎn)。
代碼如下:
@Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 設(shè)置當(dāng)前矩陣為模型視圖模式 gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); // reset the matrix to its default state // 設(shè)置視點(diǎn) GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); mTriangle.draw(gl); }
這樣,我們繪制的圖形比例就總是正確的,不再受設(shè)備的影響而被拉伸變形了。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android多媒體操作技巧匯總(音頻,視頻,錄音等)》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
相關(guān)文章
Android動(dòng)態(tài)控制狀態(tài)欄顯示和隱藏
這篇文章主要介紹了Android動(dòng)態(tài)控制狀態(tài)欄顯示和隱藏,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04Kotlin協(xié)程之Flow基礎(chǔ)原理示例解析
這篇文章主要為大家介紹了Kotlin協(xié)程之Flow基礎(chǔ)原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Android Listview滑動(dòng)時(shí)不加載數(shù)據(jù) 停止時(shí)加載數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了Android Listview滑動(dòng)時(shí)不加載數(shù)據(jù),停止時(shí)加載數(shù)據(jù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Android中FontMetrics的幾個(gè)屬性全面講解
下面小編就為大家?guī)硪黄狝ndroid中FontMetrics的幾個(gè)屬性全面講解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11DialogFragment運(yùn)行原理及使用方法詳解
這篇文章主要介紹了DialogFragment運(yùn)行原理及使用方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Android開發(fā)簡(jiǎn)單實(shí)現(xiàn)搖動(dòng)動(dòng)畫的方法
這篇文章主要介紹了Android開發(fā)簡(jiǎn)單實(shí)現(xiàn)搖動(dòng)動(dòng)畫的方法,結(jié)合實(shí)例形式分析了Android搖動(dòng)動(dòng)畫的布局與功能簡(jiǎn)單實(shí)現(xiàn)方法,需要的朋友可以參考下2017-10-10Android省市區(qū)三級(jí)聯(lián)動(dòng)控件使用方法實(shí)例講解
最近有需求需要實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng),但是發(fā)現(xiàn)之前的實(shí)現(xiàn)不夠靈活,自己做了一些優(yōu)化。下面通過實(shí)例代碼給大家介紹下Android省市區(qū)三級(jí)聯(lián)動(dòng)控件使用方法2017-01-01Android:利用SharedPreferences實(shí)現(xiàn)自動(dòng)登錄
本篇文章主要介紹了Android實(shí)現(xiàn)自動(dòng)登錄,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11