<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 189,comments - 115,trackbacks - 0

    LiveWallPaper 讓您的壁紙動起來 連載(三)——OpenGL ES特輯

    http://www.cnblogs.com/ClassroomStudio/archive/2010/08/15/CS_wallpaper_3OpenGLES.html

     

    CS——LiveWallPaper  動態(tài)壁紙程序開發(fā)(三)之 OpenGL ES 持續(xù)更新中

                         首屆 Google 暑期大學(xué)生博客分享大賽——2010 Android 篇

                                 《Ed Burnette's  Hello,Android  Third Edition》 重點篇章讀書學(xué)習(xí)改編筆記

      

       上回書說到OpenGL ES來構(gòu)建我們的立方體,那我們就先要了解一下何為OpenGL 以及OpenGL ES。

     

       OpenGL的前世今生

     

        1992年Silicon Graphics 開發(fā)出了OpenGL。它從此開始為程序員提供一個統(tǒng)一的平臺讓他們能夠駕馭來自不同生產(chǎn)商的硬件。它的核心,OpenGL迎合了三維圖形開發(fā)的一些經(jīng)典 概念如viewpoints和lighting并試圖讓開發(fā)者可以基本不去考慮錯綜復(fù)雜的硬件層就能實現(xiàn)3D的效果。您可以瀏覽http://www.opengl.org了解OpenGL的更多內(nèi)容。

        不過正是因為當(dāng)初它是為工作站設(shè)計的,所以O(shè)penGL對于一部手機來說實在是太大了。所以Google Android采用了OpenGL的一個子集——(OpenGL for Embedded Systems 針對嵌入式系統(tǒng)的OpenGL 簡稱OpenGL ES)。這個標(biāo)準(zhǔn)是由Intel、AMD、Nividia、Nokia、SONY、三星等行業(yè)巨頭共同支持的 Khronos Group行業(yè)協(xié)會提出來的,包括Android、塞班和Iphone在內(nèi)的主要手機平臺都采用了這個庫。雖然他們彼此之間還是有著細(xì)微的差別。您可以瀏 覽http://www.khronos.org/opengles了解OpenGL ES的更多內(nèi)容。

        幾乎每種計算機語言都有他自己與OpenGL ES相綁定的部分。當(dāng)然JAVA也不例外。在JAVA Specification Request(JSR)239中定義了這部分綁定。

     

        Android的OpenGL ES

     

        OpenGL ES 1.0 基于完整的OpenGL 1.3,而 ES 1.1 基于 OpenGL 1.5。JSR 239 有兩個版本:一個原有的1.0 和正式的1.0.1。而我們這次使用的便是OpenGL ES1.1

        不過從Android2.2開始,OpenGL ES 2.0開始通過android.opengl 包得到支持。您也可以通過NDK來調(diào)用它。OpenGL ES 2.0  。不過還沒有對應(yīng)于OpenGL ES 2.0的JSR標(biāo)準(zhǔn)。如下圖五所示

      

                                                         圖五

     

        現(xiàn)在讓我們用OpenGL ES來建立我們自己的立方體模型吧。 

              

    GLCube.java
    1 package org.example.opengl;
    2  -
    3  - import java.nio.ByteBuffer;
    4  - import java.nio.ByteOrder;
    5  5 import java.nio.IntBuffer;
    6  -
    7  - import javax.microedition.khronos.opengles.GL10;
    8  -
    9  - import android.content.Context;
    10  10 import android.graphics.Bitmap;
    11  - import android.graphics.BitmapFactory;
    12  - import android.opengl.GLUtils;
    13  -
    14  - class GLCube {
    15 private final IntBuffer mVertexBuffer;
    16  - public GLCube() {
    17  - int one = 65536;
    18  - int half = one / 2;
    19  - int vertices[] = {
    20 //
    21  - -half, -half, half, half, -half, half,
    22  - -half, half, half, half, half, half,
    23  - //
    24  - -half, -half, -half, -half, half, -half,
    25 half, -half, -half, half, half, -half,
    26  - //
    27  - -half, -half, half, -half, half, half,
    28  - -half, -half, -half, -half, half, -half,
    29  - //
    30 half, -half, -half, half, half, -half,
    31  - half, -half, half, half, half, half,
    32  - //
    33  - -half, half, half, half, half, half,
    34  - -half, half, -half, half, half, -half,
    35 //
    36  - -half, -half, half, -half, -half, -half,
    37  - half, -half, half, half, -half, -half, };
    38  -

    45 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    46  - vbb.order(ByteOrder.nativeOrder());
    47  - mVertexBuffer = vbb.asIntBuffer();
    48  - mVertexBuffer.put(vertices);
    49  - mVertexBuffer.position(0);
    50  5 }- public void draw(GL10 gl) {
    51  - gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
    52  -
    53 gl.glColor4f(1, 1, 1, 1);
    54  - gl.glNormal3f(0, 0, 1);
    55  - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
    56  - gl.glNormal3f(0, 0, -1);
    57  - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
    58
    59  - gl.glColor4f(1, 1, 1, 1);
    60  - gl.glNormal3f(-1, 0, 0);
    61  - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
    62  - gl.glNormal3f(1, 0, 0);
    63 gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
    64  -
    65  - gl.glColor4f(1, 1, 1, 1);
    66 - gl.glNormal3f(0, 1, 0);
    67 - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
    68 gl.glNormal3f(0, -1, 0);
    69 - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
    70 - }
    71 - }

     

         在上述代碼的第19行的矩陣通過點坐標(biāo)確定了立方體的各個頂點。我們都知道立方體的每一個面都是個正方形。而這個正方形又是由兩個等腰直角三角形組成的。 我們可以使用OpenGL中一個常用的繪圖模型——GL_TRIANGLE_STRIP來畫這個正方形。在這個模型中,我們指定兩個起始點,隨后標(biāo)出的每 一個點都將與起始點確定一個三角形。這是在圖形加速硬件上繪出大量幾何圖形的一種十分快捷的方法。需要注意的是每個點都有x、y、z三個坐標(biāo)。x軸指向屏 幕右端、y軸指向屏幕上端而z軸則指向屏幕外朝向用戶的視角。在代碼第45行繪圖方法中,我們使用構(gòu)造的VertexBuffer并且為立方體的六條邊畫 出六個不同向的等腰直角三角形。在項目實戰(zhàn)中,您可能會把幾個調(diào)用組合在一或兩個strips中,因為您代碼中的OpenGL命令調(diào)用越少,您的程序運行 起來越快。

     

      光、動作與質(zhì)地

     

             在真實的的生活中,我們周圍有很多光源如太陽、燈光、火炬或是螢火蟲的生物光。為了打造虛擬的3D世界,OpenGL讓我們可以在場景中給出8種光源。并 且如果我們想要它成為一個動態(tài)的背景,那么就一定要加入動作。當(dāng)然這還不夠,如果不給它加入質(zhì)地(材質(zhì))的話,沒人會相信它是個真東西。那在接下來的代碼中我們將一一實現(xiàn)這些功能。

      

     

     

    GlRenderer.java
    1 package org.example.opengl;
    2
    3 import javax.microedition.khronos.egl.EGLConfig;
    4 import javax.microedition.khronos.opengles.GL10;
    5
    6 import android.content.Context;
    7 import android.opengl.GLSurfaceView;
    8 import android.opengl.GLU;
    9 import android.util.Log;
    10
    11 class GLRenderer implements GLSurfaceView.Renderer {
    12 private static final String TAG = "GLRenderer";
    13 private final Context context;
    14
    15
    16 private final GLCube cube = new GLCube();
    17
    18
    19 private long startTime;
    20 private long fpsStartTime;
    21 private long numFrames;
    22
    23
    24
    25 GLRenderer(Context context) {
    26 this.context = context;
    27 }
    28
    29
    30
    31 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    32

    37 boolean SEE_THRU = false;
    38 // 定義了一個布爾變量用于設(shè)置是否使程序執(zhí)行第79行使立方體變得透明的語句
    39
    40 startTime = System.currentTimeMillis();
    41 fpsStartTime = startTime;
    42 numFrames = 0;
    43
    44
    45 // 定義光源
    46
    47 float lightAmbient[] = new float[] { 0.2f, 0.2f, 0.2f, 1 };
    48 float lightDiffuse[] = new float[] { 1, 1, 1, 1 };
    49 float[] lightPos = new float[] { 1, 1, 1, 1 };
    50 gl.glEnable(GL10.GL_LIGHTING);
    51 gl.glEnable(GL10.GL_LIGHT0);
    52 gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
    53 gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
    54 gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);
    55
    56
    57 // 立方體的材質(zhì),這可以決定光照在它上面的效果 漫反射還是鏡面反射。
    58
    59 float matAmbient[] = new float[] { 1, 1, 1, 1 };
    60 float matDiffuse[] = new float[] { 1, 1, 1, 1 };
    61 gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT,
    62 matAmbient, 0);
    63 gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE,
    64 matDiffuse, 0);
    65
    66
    67
    68 // 設(shè)置我們需要的各種參數(shù)
    69 gl.glEnable(GL10.GL_DEPTH_TEST);
    70 gl.glDepthFunc(GL10.GL_LEQUAL);
    71 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    72
    73 // 選項:禁用抖動特效,以提高性能。
    74 // gl.glDisable(GL10.GL_DITHER);
    75
    76
    77
    78 // 如上面提到的使透明的語句
    79 if (SEE_THRU) {
    80 gl.glDisable(GL10.GL_DEPTH_TEST);
    81 gl.glEnable(GL10.GL_BLEND);
    82 gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
    83 }
    84
    85
    86 // 啟用紋理特效
    87 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    88 gl.glEnable(GL10.GL_TEXTURE_2D);
    89
    90 // 將一張點陣圖加載為立方體的紋理。
    91 GLCube.loadTexture(gl, context, R.drawable.android);
    92
    93
    94
    95
    96 }
    97
    98
    99
    100
    101 public void onSurfaceChanged(GL10 gl, int width, int height) {
    102
    103 // ...
    104
    105
    106 // 定義視角
    107 gl.glViewport(0, 0, width, height);
    108 gl.glMatrixMode(GL10.GL_PROJECTION);
    109 gl.glLoadIdentity();
    110 float ratio = (float) width / height;
    111 GLU.gluPerspective(gl, 45.0f, ratio, 1, 100f);
    112
    113 }
    114
    115
    116
    117
    118
    119 public void onDrawFrame(GL10 gl) {
    120
    121 // ...
    122
    123
    124
    125
    126 // 清到黑屏
    127 gl.glClear(GL10.GL_COLOR_BUFFER_BIT
    128 | GL10.GL_DEPTH_BUFFER_BIT);
    129
    130 // ...
    131 gl.glMatrixMode(GL10.GL_MODELVIEW);
    132 gl.glLoadIdentity();
    133 gl.glTranslatef(0, 0, -3.0f);
    134
    135 // 您的其它的繪圖命令可以寫在這里。
    136
    137
    138 // 根據(jù)時間設(shè)置每次旋轉(zhuǎn)的角度
    139 long elapsed = System.currentTimeMillis() - startTime;
    140 gl.glRotatef(elapsed * (25f / 1000f), 0, 1, 0); //每秒鐘它都會沿Y軸轉(zhuǎn)25度
    141 gl.glRotatef(elapsed * (10f / 1000f), 1, 0, 0); //每秒鐘它沿x軸轉(zhuǎn)10度
    142
    143
    144 // 畫出模型
    145 cube.draw(gl);
    146
    147
    148 // 隨時跟蹤得出的幀數(shù)
    149
    150 numFrames++;
    151 long fpsElapsed = System.currentTimeMillis() - fpsStartTime;
    152 if (fpsElapsed > 3 * 1000) { // 每3秒一次
    153 float fps = (numFrames * 1000.0F) / fpsElapsed;
    154 Log.d(TAG, "Frames per second: " + fps + " (" + numFrames
    155 + " frames in " + fpsElapsed + " ms)");
    156 fpsStartTime = System.currentTimeMillis();
    157 numFrames = 0;
    158 }
    159
    160
    161
    162
    163
    164 }
    165
    166
    167
    168 }
    169

        

     在代碼的第69行,我們設(shè)置了一組OpenGL 參數(shù)。當(dāng)然OpenGL那幾十個參數(shù)都是通過glEnable( ) 來啟用,通過 glDisable( )來禁用。在下面列出的是最常用到的參數(shù)選項。
          選項說明:

     

    GL_BLEND 允許將新進(jìn)來的顏色值與已經(jīng)在緩沖區(qū)中的顏色值融合。
    GL_CULL_FACE

    Ignore polygons(多邊形) based on their

    winding (clockwise or counterclockwise

    (順時針還是逆時針)) in window coordinates.

     This is a cheap way to eliminate back faces.

    (正在琢磨如何解釋)

    GL_DEPTH_TEST

    進(jìn)行更深入的比較,并且更新緩沖區(qū)的深度

    忽略掉像素數(shù)已經(jīng)遠(yuǎn)高于之前繪制好的

    GL_LIGHTi Include light number i when ?guring out an object’s
    brightness and color.(正在琢磨如何解釋)

    GL_LIGHTING 開啟照明和材質(zhì)計算。
    GL_LINE_SMOOTH 繪制抗鋸齒線(無鋸齒線)。
    GL_MULTISAMPLE 啟動多重采樣抗鋸齒和其他效果。
    GL_POINT_SMOOTH 繪制抗鋸齒點。
    GL_TEXTURE_2D 使用紋理繪制表面。

       
        除了GL_DITHER和GL_MULTISAMPLE以外其他選項都是默認(rèn)關(guān)閉的。請注意,我們啟動的任何一項特性都會帶有一定的性能開銷。

       

        請注意一下第150行開始的代碼,請問我們?yōu)槭裁匆獧z測每秒鐘的幀數(shù)呢?

     

        為的是檢測畫面的流暢程度

     

        我們?nèi)绾谓缍鲿吵潭取σ粋€游戲或 對圖形加速能力要求較高的程序,可以通過它刷洗屏幕的速度來看出它的流暢度。我們經(jīng)常使用FPS即每秒幀數(shù)來衡量。不同的人對于流暢與否的尺度是不同的。 一般來講 15–30FPS對于普通玩家來說就可以接受了。但較骨灰級的玩家來說可能要60FPS或是更高才能讓他們滿意。作為專業(yè)的程序員,我們應(yīng)該向 著60FPS的目標(biāo)而努力。但這可能不太現(xiàn)實,畢竟一些服務(wù)于低端的Android手機,他們的3D硬件加速相對于他們的分辨率要弱一些。當(dāng)然對于越快的 設(shè)備,達(dá)到這個標(biāo)準(zhǔn)越是沒有問題。高幀頻是具有挑戰(zhàn)性的,因為我們要在60fps下 即1/60th秒(16.67毫秒之間)調(diào)用onDrawFrame()做一切需要做的事情,包括任何動畫、物理計算、游戲計算,再加上花費在實際繪制圖形上的時間。而唯一能夠檢驗程序的FPS是否達(dá)到了我們設(shè)計的預(yù)期的方法,就是就是通過程序自己來測量它。

     

         如上面的代碼所示。每三秒它就會將您的平均FPS值發(fā)到Android系統(tǒng)的Log Messages上。如果這個數(shù)字低于您的預(yù)期,您就可以調(diào)整您的算法并重試。當(dāng)然AVD畢竟是模擬。我們最終還是要看實際真機測試。

     

              Continuous update......

       

    posted on 2011-08-16 09:44 MEYE 閱讀(893) 評論(0)  編輯  收藏 所屬分類: Android3D
    主站蜘蛛池模板: 免费人妻无码不卡中文字幕系| 麻豆国产精品免费视频| 7m凹凸精品分类大全免费| 免费a级毛片无码a∨蜜芽试看| 免费人成视频在线观看视频| 亚洲国产精品VA在线看黑人| 亚洲偷自精品三十六区| 一出一进一爽一粗一大视频免费的| 91精品全国免费观看含羞草| 国产午夜无码视频免费网站| 亚洲成AV人片在线播放无码| 亚洲精品人成网线在线播放va| 爽爽爽爽爽爽爽成人免费观看| 人禽杂交18禁网站免费| 亚洲另类激情综合偷自拍图| 亚洲色大18成人网站WWW在线播放| 久久国产一片免费观看| 成人免费a级毛片| 久久被窝电影亚洲爽爽爽| 亚洲乱亚洲乱妇无码| 久久久久国产免费| 免费中文字幕在线观看| 亚洲成人黄色在线观看| 免费国产a理论片| 亚洲精品免费网站| 亚洲精品无码永久在线观看你懂的| 亚洲AV成人影视在线观看| 久久免费视频观看| 全部免费a级毛片| 亚洲人成网网址在线看| 中文毛片无遮挡高清免费| 国产精品免费看久久久久| 久久亚洲春色中文字幕久久久| 一级毛片免费不卡| 日韩中文字幕免费| 亚洲a级成人片在线观看| 国产成人免费AV在线播放 | 午夜小视频免费观看| 91亚洲精品第一综合不卡播放| 男女一边摸一边做爽的免费视频| 精品免费久久久久久成人影院|