日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Android平台下OpenGL初步

發(fā)布時(shí)間:2025/3/20 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android平台下OpenGL初步 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Android OpenGL ES 開發(fā)教程 從入門到精通?http://blog.csdn.net/zhoudailiang/article/details/50176143

http://blog.csdn.net/jason0539/article/details/9164885

1、GLSurfaceView

?

GLSurfaceView是Android應(yīng)用程序中實(shí)現(xiàn)OpenGl畫圖的重要組成部分。GLSurfaceView中封裝了一個(gè)Surface。而android平臺(tái)下關(guān)于圖像的現(xiàn)實(shí),差不多都是由Surface來實(shí)現(xiàn)的。

2、Renderer

?

有了GLSurfaceView之后,就相當(dāng)于我們有了畫圖的紙。現(xiàn)在我們所需要做的就是如何在這張紙上畫圖。所以我們需要一支筆。
Renderer是GLSurfaceView的內(nèi)部靜態(tài)接口,它就相當(dāng)于在此GLSurfaceView上作畫的筆。我們通過實(shí)現(xiàn)這個(gè)接口來“作畫”。最后通過GLSurfaceView的setRenderer(GLSurfaceView.Renderer renderer)方法,就可以將紙筆關(guān)聯(lián)起來了。


實(shí)現(xiàn)Renderer需要實(shí)現(xiàn)它的三個(gè)接口:onSurfaceCreated(GL10 gl, EGLConfig config)、 onSurfaceChanged(GL10 gl, int width, int height)、onDrawFrame(GL10 gl)。下面就這三個(gè)接口的具體意義做個(gè)簡(jiǎn)單的介紹。

2.1、onSurfaceCreated

此方法看名字就知道它是在Surface創(chuàng)建的時(shí)候被調(diào)用的。因此我們可以在這個(gè)函數(shù)的實(shí)現(xiàn)中做一些初始化的工作。例如取出文房四寶、鋪好畫布、調(diào)好顏料之類的。它的函數(shù)原
型如下:
public abstract void onSurfaceCreated (GL10 gl, EGLConfig config)
第二個(gè)參數(shù)在文檔中沒有關(guān)于它的任何public方法和域。因此我們可以不用管它。
第一個(gè)參數(shù)非常重要。如果說Renderer是畫筆的話,那么這個(gè)gl參數(shù),就可以說是我們的手了。如何操作這支畫筆,都是它說了算!所以我們絕大部分時(shí)候都是通過這個(gè)叫做gl的手來指揮Renderer畫圖的。

2.2 onSurfaceChanged

當(dāng)GLSurfaceView大小改變時(shí),對(duì)應(yīng)的Surface大小也會(huì)改變。值得注意的是,在Surface剛創(chuàng)建的時(shí)候,它的size其實(shí)是0,也就是說在畫第一次圖之前它也會(huì)被調(diào)用一次的。(而且對(duì)于很多時(shí)候,Surface的大小是不會(huì)改變的,那么此函數(shù)就只在創(chuàng)建之初被調(diào)用一次而已)

原型如下:
public abstract void onSurfaceChanged (GL10 gl, int width, int height)
同樣的,畫圖的手是必需的。
另外值得注意的是,它告訴了我們這張紙有多高多寬。這點(diǎn)很重要。因?yàn)樵趏nSurfaceCreated的時(shí)候我們是不知道紙的寬高的,所以有一些和長(zhǎng)寬相關(guān)的初始化工作還得在此函數(shù)中來做。

2.3 onDrawFrame

好了,我們的初始化工作做得差不多了,那么現(xiàn)在就是該真刀真槍畫畫的時(shí)候了!此函數(shù)就是真正給你畫畫用的。每調(diào)用一次就畫一幅圖。可能的疑問是這個(gè)函數(shù)什么時(shí)候會(huì)被調(diào)
用呢?最開始的時(shí)候肯定是會(huì)被調(diào)用的。以后會(huì)有兩種模式供你選擇:

  • RENDERMODE_CONTINUOUSLY
  • RENDERMODE_WHEN_DIRTY
  • 第一種模式(RENDERMODE_CONTINUOUSLY):
    連續(xù)不斷的刷,畫完一幅圖馬上又畫下一幅。這種模式很明顯是用來畫動(dòng)畫的;


    第二種模式(RENDERMODE_WHEN_DIRTY):
    只有在需要重畫的時(shí)候才畫下一幅。這種模式就比較節(jié)約CPU和GPU一些,適合用來畫不經(jīng)常需要刷新的情況。多說一句,系統(tǒng)如何知道需要重畫了呢?當(dāng)然是你要告訴它……
    調(diào)用GLSurfaceView的requestRender ()方法,告訴它,你臟了。


    這兩種模式在什么地方設(shè)置呢? GLSurfaceView的setRenderMode(int renderMode)方法。可以供你設(shè)置你需要的刷新模式。


    還是來看看這個(gè)函數(shù)的原型吧: public abstract void onDrawFrame (GL10 gl) 很簡(jiǎn)單,只有手。

    ?

    3、 Android下OpenGL繪圖基本流程:

    ?

    我們從畫一個(gè)三角形開始說起:

    3.1 MyRender

    經(jīng)過前面的介紹,我們應(yīng)該知道現(xiàn)在需要做的事,就是寫好Renderer的三個(gè)接口方法。
    我們需要重新寫一個(gè)類實(shí)現(xiàn)它,然后重寫這三個(gè)方法。
    class MyRender implements GLSurfaceView.Renderer
    OK,筆已經(jīng)拿好了。“鋪好紙”是非常關(guān)鍵的一步。雖然我們說GLSurfaceView就是我們作圖的紙,但是“鋪”好這張紙,卻也非常的重要。

    ?

    下面我們重點(diǎn)講下,這紙?jiān)撛趺翠仭penGL這張紙可不是一般的紙啊。最起碼,它是三維的。然而實(shí)際的顯示屏幕卻是一個(gè)平面。所以這紙還不好“鋪”。


    首先,不一定整張紙都用來作畫吧,Surface不一定全部都用上(當(dāng)然,一般情況下我們是全部用上的)。那么我們需要計(jì)劃好,哪部分區(qū)域用來作畫。
    gl.glViewport(0, 0, width, height);
    根據(jù)這里的參數(shù)width和height,我們可以知道這個(gè)寬高需要在onSurfaceChanged里得知。


    然后,這一步很關(guān)鍵。如何在平面上畫三維坐標(biāo)的點(diǎn)或圖形呢?OpenGL有一個(gè)坐標(biāo)系,如下圖:


    我們需要將這個(gè)坐標(biāo)系和我們的GLSurfaceView里的Surface做一個(gè)映射關(guān)系。
    glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glFrustumf(-400, 400, -240, 240, 0.3f, 100);

    ?

    glMatrixMode(GL10.GL_PROJECTION); 是說我們現(xiàn)在改變的是坐標(biāo)系與Surface的映射關(guān)系(投影矩陣)。

    下一句 gl.glLoadIdentity(); 是將以前的改變都清掉(之前對(duì)投影矩陣的任何改變)。

    glFrustumf (float left, float right, float bottom, float top, float zNear, float zFar) 這個(gè)函數(shù)非常Powerful。它實(shí)現(xiàn)了Surface和坐標(biāo)系之間的映射關(guān)系。它是以透視投影的方式來進(jìn)行映射的。


    透視投影的意思見下圖:

    ?


    映射說明:
    1、 前面一個(gè)矩形表示的是我們平面作圖的范圍。即Surface的作圖范圍。它有四條邊,
    我們將它們暫時(shí)命名edgeLeft、edgeRight、edgeTop、edgeBottom。
    2、 glFrustumf 參數(shù)中的left、right、bottom、top指的是作圖范圍的四條edge在OpenGL x = -400的位置。同理top、right、bottom的值表示的是edgeRight、edgeTop、edgeBottom這幾條邊在坐標(biāo)系中的位置。
    3、上面第二點(diǎn)定出了作圖范圍的x和y的范圍。那么對(duì)于3D的OpenGL這張紙來說,我們還需要定出z的范圍。首先,要想象一下,相機(jī)或者眼睛在坐標(biāo)系的哪個(gè)位置?
    默認(rèn)的眼睛的位置在OpenGL坐標(biāo)的原點(diǎn)處(0,0,0)。視線方向是平行于Z軸往里看。
    near表示的是眼睛到作圖平面的距離(絕對(duì)值哦!),far表示眼睛到最遠(yuǎn)可見處的平面范圍。于是,默認(rèn)情況下z的作圖范圍就是在-near到-far的位置。
    4、好了,我們已經(jīng)確定好x、y、z方向的作圖范圍了。回過頭來,就可以發(fā)現(xiàn),這張“立體”的紙,是一個(gè)方椎體切去頭部的平截頭體。我們所畫的物體坐標(biāo)落在這個(gè)區(qū)域范圍內(nèi)的部分將可以被我們看到(即在屏幕里畫出來)。OK,至此,我們把紙終于鋪好了。

    ?

    glMatrixMode函數(shù)的選項(xiàng)(參數(shù))有后面三種:GL_PROJECTION,GL_MODELVIEW和GL_TEXTURE;

    • GL_PROJECTION,是投影的意思,就是要對(duì)投影相關(guān)進(jìn)行操作,也就是把物體投影到一個(gè)平面上,就像我們照相一樣,把3維物體投到2維的平面上。這樣,接下來的語句可以是跟透視相關(guān)的函數(shù),比如glFrustum()或gluPerspective();
    • GL_MODELVIEW,是對(duì)模型視景的操作,接下來的語句描繪一個(gè)以模型為基礎(chǔ)的適應(yīng),這樣來設(shè)置參數(shù),接下來用到的就是像gluLookAt()這樣的函數(shù);
    • GL_TEXTURE,就是對(duì)紋理相關(guān)進(jìn)行操作;

    順便說下,OpenGL里面的操作,很多是基于對(duì)矩陣的操作的,比如位移,旋轉(zhuǎn),縮放,所以,
    這里其實(shí)說的規(guī)范一點(diǎn)就是glMatrixMode是用來指定哪一個(gè)矩陣是當(dāng)前矩陣,而它的參數(shù)代表要操作的目標(biāo):

    • GL_PROJECTION是對(duì)投影矩陣操作;
    • GL_MODELVIEW是對(duì)模型視景矩陣操作;
    • GL_TEXTURE是對(duì)紋理矩陣進(jìn)行隨后的操作;

    ?

    ?

    3.2 畫圖之前先構(gòu)圖


    Android 的 OpenGL 作圖,不同于一般的作圖,這點(diǎn)我們不得不感慨。它將數(shù)據(jù)和畫完全分開來。例如,我們要畫一個(gè)三角形。很顯然,三角形有三個(gè)點(diǎn)。我們?cè)诋媹D之前首先要構(gòu)圖,比如每個(gè)點(diǎn)在哪個(gè)地方。我們將這些數(shù)據(jù)放在一個(gè)一個(gè)數(shù)組緩沖區(qū)中,放好這些數(shù)據(jù)之后,再統(tǒng)一一起畫出來。

    下面,主要講下,如何將頂點(diǎn)數(shù)據(jù)和顏色數(shù)據(jù)放入符合 Android OpenGL 的數(shù)組緩沖區(qū)中。

    ?

    首先我們要明白的是,OpenGL 是一個(gè)非常底層的畫圖接口,它所使用的緩沖區(qū)存儲(chǔ)結(jié)構(gòu)是和我們的?Java?程序中不相同的。Java 是大端字節(jié)序(BigEdian),而 OpenGL 所需要的數(shù)據(jù)是小端字節(jié)序(LittleEdian)。所以,我們?cè)趯?Java 的緩沖區(qū)轉(zhuǎn)化為 OpenGL 可用的緩沖區(qū)時(shí)需要作一些工作。


    byte 數(shù)據(jù)緩沖區(qū)

    不管我們的數(shù)據(jù)是整型的還是浮點(diǎn)型的,為了完成 BigEdian 到 LittleEdian 的轉(zhuǎn)換,我們都首先需要一個(gè) ByteBuffer。我們通過它來得到一個(gè)可以改變字節(jié)序的緩沖區(qū)。

    ByteBuffer mBuffer = ByteBuffer.allocateDirect(pointCount*dimension*4);
    mBuffer.order(ByteOrder.nativeOrder());

    注意,我們應(yīng)該用“allocateDirect”來分配內(nèi)存空間,因?yàn)檫@樣才可以 order 排序。最后我們就可以通過:
    resultBuffer = mBuffer.asFloatBuffer();
    resultBuffer = mBuffer.asIntBuffer();
    將字節(jié)緩沖區(qū)轉(zhuǎn)化為整型或者浮點(diǎn)型緩沖區(qū)了。

    ?

    ?

    3.3 終于畫圖了!


    有了前面所有的準(zhǔn)備工作之后,有一個(gè)好消息可以告訴你,我們終于可以畫圖了!而且,有了前面這么多工作,真正畫圖的工作其實(shí)比較簡(jiǎn)單。


    3.3.1、清理好你的紙

    前面我們說過了,在畫圖之前,一定要把紙給清理干凈嘍:

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    另外,之前我們?cè)谟成渥鴺?biāo)系的時(shí)候,用了glMatrixMode(GL10.GL_PROJECTION);來指定改變的是投影矩陣。那么現(xiàn)在要畫圖了,所以我們需要指定改變的是“視圖矩陣”:

    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();

    ?

    3.3.2、啟用數(shù)組

    我們的前面說過,畫圖的數(shù)據(jù)都放在數(shù)組緩沖區(qū)里,最后再一起傳過來作畫。那么我們首先要告訴 OpenGL,我們需要用到哪些數(shù)組。例如我們需要頂點(diǎn)數(shù)組和顏色數(shù)組:

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

    ?

    3.3.3、指定數(shù)組數(shù)據(jù)

    我們前面已經(jīng)構(gòu)造好了我們的數(shù)據(jù)緩沖區(qū),floatBuffer(或 IntBuffer)。現(xiàn)在我們只需要將這個(gè)數(shù)據(jù)緩沖區(qū)和對(duì)應(yīng)的功能綁定起來就好了:

    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VertexBuffer);
    gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);

    這兩句話分別綁定了頂點(diǎn)數(shù)據(jù)數(shù)組和顏色數(shù)據(jù)數(shù)組。其中第一個(gè)參數(shù)表示的是每個(gè)點(diǎn)有幾個(gè)坐標(biāo)。例如頂點(diǎn),有 x、y、z值,所以是 3;而顏色是 r、g、b、a 值,所以是 4。

    ?

    3.3.4、畫圖!

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

    第一個(gè)參數(shù)指明了畫圖的類型——三角形(android 似乎只支持畫三角形、點(diǎn)、線,不支持畫多邊形)。后面兩個(gè)參數(shù)指明,從哪個(gè)頂點(diǎn)開始畫,畫多少個(gè)頂點(diǎn)。

    ?

    OK!至此,我們的第一個(gè)三角形就畫出來了,來看看效果吧。

    ?

    OpenGL ES之glFrustumf設(shè)置投影視角詳解?http://blog.csdn.net/wangyuchun_799/article/details/7841429

    -(void)setClipping
    {
    float aspectRatio;
    const float zNear = 0.1; //1
    const float zFar = 1000; //2
    const float fieldOfView = 60.0; //3
    GLfloat size;
    CGRect frame = [[UIScreen mainScreen] bounds]; //4

    aspectRatio=(float)frame.size.width/(float)frame.size.height; //5

    ?

    //Set the OpenGL projection matrix.

    glMatrixMode(GL_PROJECTION); //6
    glLoadIdentity();
    size = zNear * tanf(GLKMathDegreesToRadians (fieldOfView) / 2.0); //7
    glFrustumf(-size, size, -size /aspectRatio, size /aspectRatio, zNear, zFar); //8
    glViewport(0, 0, frame.size.width, frame.size.height); //9
    //Make the OpenGL ModelView matrix the default.
    glMatrixMode(GL_MODELVIEW); //10 }

    glFrustumf中文API文檔參考OpenGL ES之glFrustum函數(shù)

    ??????? 第1、2行指定了近裁面和遠(yuǎn)裁面的距離。這兩個(gè)值的意思是,任何遠(yuǎn)于1000或近于0.1的對(duì)象都將被過濾掉。你可能會(huì)問一千什么?就是一千!單位看你自己設(shè)想。你可以把它想象成光年,或者英尺,都無所謂。不信的話你自己隨便設(shè)置一下試試。

    ????????第3行設(shè)定視角為60度。

    ????????第4行獲取屏幕的尺寸大小。

    ????????第5行根據(jù)屏幕的尺寸計(jì)算最終屏幕的縱橫比例。它的高度和寬度的值決定了相對(duì)高度的視域(FOV),如果將其翻轉(zhuǎn)的話,將變成相對(duì)于寬度的視域。如果我們要設(shè)置一個(gè)60度視域,就像一個(gè)寬角度鏡頭,那么它將基于窗口的高度而非寬度。當(dāng)渲染到一個(gè)非正方形的屏幕上時(shí)尤為重要。

    ????????由于glfrustumf影響的是投影矩陣,所以我們需要確認(rèn)將當(dāng)前矩陣從模型視圖矩陣設(shè)置成投影矩陣。第6行就是要做這個(gè)滴。

    第7行計(jì)算錐形視角的左右上下的限制值。你可以把它想象成3D空間中的虛擬窗口。原點(diǎn)在屏幕中央,所以x軸和y軸的值都是從-size到+size。這就是為什么會(huì)有GLKMathDegreesToRadians (fieldOfView) / 2.0將窗口分為兩部分——視角的角度是從-30度到+30度的。乘以zNear就可以計(jì)算出近剪裁面在坐標(biāo)軸各個(gè)方向上的大小。這就是正切函數(shù)的作用了,眼睛在z軸上,到原點(diǎn)的距離是zNear,視域被z軸分為上下兩部分各為30度,所以就可以明白size就是近剪裁面在x和y軸上的長(zhǎng)度。

    ?? ?第8行將計(jì)算的左右上下以及近剪裁面和遠(yuǎn)剪裁面的值傳進(jìn)glFrustumf函數(shù)。這里下邊和上邊的值都除以了aspectRatio(屏幕寬高比),而左右邊沒有,這是因?yàn)檎{(diào)用glLoadIdentity函數(shù)標(biāo)準(zhǔn)化投影矩陣的時(shí)候?qū)⑺械捻旤c(diǎn)數(shù)據(jù)都標(biāo)準(zhǔn)化到了-1~1的范圍內(nèi),屏幕寬度和高度實(shí)際大小不一樣,但都被標(biāo)準(zhǔn)化成了1。所以如果左右值和上下值一樣的話得到的就是一個(gè)寬度比較大而高度比較小的長(zhǎng)方形,而不是預(yù)期的正方形,所以左右值不變,而上下值要除以寬高比。

    ????????第9行用來設(shè)置視口,一般為屏幕的大小。不過你可以根據(jù)需要來設(shè)置坐標(biāo)和寬度、高度。

    ????????第10行為將當(dāng)前的矩陣從投影矩陣設(shè)置為模型視圖矩陣。

    ??????

    ??????? 由于設(shè)置投影視角的方法基本上是固定的,只不過需要調(diào)整一下近剪裁面和遠(yuǎn)剪裁面以及視角的大小,所以可以將setClipping函數(shù)進(jìn)一步封裝為:

    -(void)setClippingWithNear:(const float)zNear far:(const float)zFar angle:(const float) fieldOfView
    {

    float aspectRatio;
    GLfloat size;
    CGRect frame = [[UIScreen mainScreen] bounds]; //4

    aspectRatio=(float)frame.size.width/(float)frame.size.height; //5

    ?

    //Set the OpenGL projection matrix.

    glMatrixMode(GL_PROJECTION); //6
    glLoadIdentity();
    size = zNear * tanf(GLKMathDegreesToRadians (fieldOfView) / 2.0); //7
    glFrustumf(-size, size, -size /aspectRatio, size /aspectRatio, zNear, zFar); //8
    glViewport(0, 0, frame.size.width, frame.size.height); //9
    //Make the OpenGL ModelView matrix the default.
    glMatrixMode(GL_MODELVIEW); //10

    }

    ?初識(shí)openGL---openGL學(xué)習(xí)筆記(一)?http://blog.csdn.net/a358333644/article/details/50732170

    openGL:

    openGL是用C語言實(shí)現(xiàn)的,而我們作為安卓開發(fā)者,嚴(yán)格來講,我們使用的是es,也就是openGL es,原因無非就像數(shù)據(jù)庫(kù)一樣,安卓上使用的數(shù)據(jù)庫(kù)永遠(yuǎn)不可能是MySQL之類的,因?yàn)榻K端講究輕量。

    接下來我們來創(chuàng)建第一個(gè)openGL項(xiàng)目:

    首先我們來了解一下GLSurfaceView這個(gè)類,這個(gè)類相當(dāng)于是在屏幕上的一個(gè)模板,如下圖。

    所以,創(chuàng)建一個(gè)類繼承GLSurfaceView之后,我們就可以new出GLSurfaceView類的對(duì)象,調(diào)用GLSurfaceView類的對(duì)象的setRenderer()方法,就可以對(duì)GLSurfaceView進(jìn)行渲染,而我們的主要工作是,如何進(jìn)行渲染。

    class MyGLSurfaceView extends GLSurfaceView{public MyGLSurfaceView(Context context) {super(context);}public MyGLSurfaceView(Context context, AttributeSet attrs) {super(context, attrs);}}

    ?

    ?

    那么就要自定義一個(gè)渲染器:new一個(gè)類實(shí)現(xiàn)Renderer,需重寫三個(gè)方法:onSurfaceCreated,onSurfaceChanged和onDrawFrame。

    ?

    //自定義渲染器 class MyRenderer implements GLSurfaceView.Renderer{//表層創(chuàng)建時(shí)調(diào)用@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {//設(shè)置清屏色gl.glClearColor(0, 0, 0, 1);//啟用頂點(diǎn)緩沖區(qū)gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);}//當(dāng)表層size改變時(shí)調(diào)用@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {//設(shè)置視口,輸出畫面的區(qū)域。gl.glViewport(0,0,width,height);//寬高比float ratio = (float)width/(float)height;//矩陣模式,投影矩陣,openGL基于狀態(tài)機(jī)。gl.glMatrixMode( GL10.GL_PROJECTION );//加載單位矩陣gl.glLoadIdentity();//設(shè)置平截頭體gl.glFrustumf(-1f,1f,-ratio,ratio,3,7); //-1f,1f為平截頭體左右大小比,-ratio,ratio為平截頭體底面和頂面,3,7為近平面和原平面距離}//繪圖調(diào)用@Overridepublic void onDrawFrame(GL10 gl) {//清除顏色緩沖區(qū)。gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//模型視圖矩陣。gl.glMatrixMode( GL10.GL_MODELVIEW );//加載單位矩陣。gl.glLoadIdentity();//0,0,5:放置眼球的坐標(biāo)。//0,0,0:眼球觀察的中心點(diǎn)坐標(biāo)。//0,1,0:指定眼球向上的向量。GLU.gluLookAt(gl,0,0,5,0,0,0,0,1,0);/*** 畫三角形*///三角形頂點(diǎn)坐標(biāo)float [] coords = {0f,0.5f,0f,-0.5f,-0.5f,0f,0.5f,-0.5f,0f};//分配字節(jié)緩存空間,存放頂點(diǎn)坐標(biāo)數(shù)據(jù)。ByteBuffer ibb = ByteBuffer.allocateDirect(coords.length * 4);//設(shè)置順序(本地順序)。ibb.order(ByteOrder.nativeOrder());//放置頂點(diǎn)數(shù)組。FloatBuffer fbb = ibb.asFloatBuffer();fbb.put(coords);//定位指針位置,從該位置開始讀取頂點(diǎn)數(shù)據(jù)。ibb.position(0);//設(shè)置繪圖顏色:紅色。gl.glColor4f(1f,0,0,1f);//3→三維點(diǎn),使用三個(gè)坐標(biāo)表示一個(gè)點(diǎn)。//每個(gè)點(diǎn)的數(shù)據(jù)類型。//0→跨度。//ibb指定緩沖區(qū)。gl.glVertexPointer(3,GL10.GL_FLOAT,0,ibb);//畫數(shù)組gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);} }

    顯而易見,onSurfaceCreated和onSurfaceChanged都是在做初始化工作,關(guān)鍵的是onDrawFrame方法:

    ?

    需要注意的是,onSurfaceChanged中設(shè)置的平截頭體,所謂平截頭體就是一個(gè)類似棱錐的區(qū)域,如下圖:

    ?


    ?

    最左邊的眼睛通過中間墻上的孔,可以看得見與孔相同比例的空間,那么墻上的孔到墻后景物中間的四棱錐,就是一個(gè)平截頭體。墻上的孔叫近平面,后方景物叫遠(yuǎn)平面。因?yàn)楣馐侵鄙涞?#xff0c;所以,我們只要指定好近平面的比例,以及圖中兩段紅線的比例,那么就能確定遠(yuǎn)平面,繼而確定平截頭體。

    ?

    確定了平截頭體之后,就要關(guān)注onDrawFrame方法,類似于拍照的過程,我確定了要拍什么之后,還是要確定拍照時(shí)候要確定相機(jī)的位置,相機(jī)的朝向,相機(jī)的反正。這個(gè)三個(gè)屬性就對(duì)應(yīng)了程序中的GLU.gluLookAt()方法。詳細(xì)參數(shù)見代碼注釋。

    ?

    通過這幾步之后,還是不能拍照,因?yàn)槲覀冞€有一些參數(shù)沒有設(shè)置,比如繪圖顏色。上例程序中是畫了一個(gè)三角形,那么還需指定三角形的三點(diǎn)坐標(biāo)等等,具體細(xì)節(jié)代碼中注釋的很詳細(xì),不再贅述。

    總結(jié)

    以上是生活随笔為你收集整理的Android平台下OpenGL初步的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。