安卓3D游戲開(kāi)發(fā)教程 安卓學(xué)習(xí)_第1頁(yè)
安卓3D游戲開(kāi)發(fā)教程 安卓學(xué)習(xí)_第2頁(yè)
安卓3D游戲開(kāi)發(fā)教程 安卓學(xué)習(xí)_第3頁(yè)
安卓3D游戲開(kāi)發(fā)教程 安卓學(xué)習(xí)_第4頁(yè)
安卓3D游戲開(kāi)發(fā)教程 安卓學(xué)習(xí)_第5頁(yè)
已閱讀5頁(yè),還剩49頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、安卓3D游戲開(kāi)發(fā)教程本帖最后由huzht 于2010-4-25 07:58 編輯這幾篇Android 3D游戲開(kāi)發(fā)的文章原文出自一位德國(guó)人Martin 在寫(xiě)的文章,有l(wèi)ixinso翻譯為中文。第一部分首先介紹OpenGL相關(guān)的術(shù)語(yǔ),并引導(dǎo)你開(kāi)始3D開(kāi)發(fā)的第一步。這個(gè)關(guān)于3D游戲的系列的叫做V ortex .這個(gè)教程主要focus在3D編程上,其他的東西比如菜單和程序生命周期雖然是代碼的一部分,但是在這里不會(huì)被提到。首先開(kāi)始介紹OpenGL的術(shù)語(yǔ)。頂點(diǎn)Vertex頂點(diǎn)是3D空間中的一個(gè)點(diǎn),也是許多對(duì)象的基礎(chǔ)元素。在OpenGL中你可以生命少至二維坐標(biāo)(X,Y,多至四維(X,Y,Z,W. w軸是可

2、選的,默認(rèn)的值是1.0. Z軸也是可選的,默認(rèn)為0. 在這個(gè)系列中,我們將要用到3個(gè)主要的坐標(biāo)X,Y,Z,因?yàn)閃一般都是被用來(lái)作為占位符。vertex的復(fù)數(shù)是vertices(這對(duì)非英語(yǔ)母語(yǔ)的人來(lái)說(shuō)比較重要,因?yàn)檫@容易產(chǎn)生歧義。所有的對(duì)象都是用vertices作為它們的點(diǎn),因?yàn)辄c(diǎn)就是vertex。三角形Triangle三角形需要三個(gè)點(diǎn)才能創(chuàng)建。因此在OpenGL中,我們使用3個(gè)頂點(diǎn)來(lái)創(chuàng)建一個(gè)三角形。多邊形Polygon多邊形是至少有3個(gè)連接著的點(diǎn)組成的一個(gè)對(duì)象。三角形也是一個(gè)多邊形。圖元Primitives一個(gè)Primitive是一個(gè)三維的對(duì)象,使用三角形或者多邊形創(chuàng)建。形象的說(shuō),一個(gè)有500

3、00個(gè)頂點(diǎn)的非常精細(xì)的模型是一個(gè)Primitive,同樣一個(gè)只有500個(gè)頂點(diǎn)的低模也叫做一個(gè)Primitive。現(xiàn)在我們可以開(kāi)始變成了。創(chuàng)建一個(gè)工程交V ortex,activity也是這個(gè)名字。我們的工程應(yīng)該大概是這個(gè)樣子的: package com.droidnova.android.games.vortex;import android.app.Activity;import android.os.Bundle;public class Vortex extends Activity private static final String LOG_TAG = Vortex.class.g

4、etSimpleName(;private VortexView _vortexView;Overrideprotected void onCreate(Bundle savedInstanceState super.onCreate(savedInstanceState;_vortexView = new V ortexView(this;setContentView(_vortexView;復(fù)制代碼如上圖所示,我們已經(jīng)添加了View。讓我們看一下V ortexView類(lèi)。package com.droidnova.android.games.vortex;import android.co

5、ntent.Context;import android.opengl.GLSurfaceView;public class VortexView extends GLSurfaceView private static final String LOG_TAG = VortexView.class.getSimpleName(;private VortexRenderer _renderer;public VortexView(Context context super(context;_renderer = new VortexRenderer(;setRenderer(_renderer

6、;復(fù)制代碼如上所示,我們繼承了GLSurfaceView是因?yàn)樗鼤?huì)幫助我們畫(huà)3D圖像。接下來(lái)看V ortexRenderer類(lèi)。一個(gè)Renderer包含畫(huà)一幀所必需的所有東西。引用自這兒references 。Renderer負(fù)責(zé)OpenGL call來(lái)render一個(gè)幀。來(lái)看一下這個(gè)類(lèi):package com.droidnova.android.games.vortex;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.o

7、pengl.GLSurfaceView;public class VortexRenderer implements GLSurfaceView.Renderer private static final String LOG_TAG = VortexRenderer.class.getSimpleName(;private float _red = 0.9f;private float _green = 0.2f;private float _blue = 0.2f;Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config

8、/ Do nothing special.Overridepublic void onSurfaceChanged(GL10 gl, int w, int h gl.glViewport(0, 0, w, h;Overridepublic void onDrawFrame(GL10 gl / define the color we want to be displayed as the "clipping wall"gl.glClearColor(_red, _green, _blue, 1.0f;/ clear the color buffer to show the C

9、learColor we called above.gl.glClear(GL10.GL_COLOR_BUFFER_BIT;復(fù)制代碼好,我們做了什么?首先我們實(shí)現(xiàn)了GLSurfaceView.Renderer這個(gè)接口,主要是實(shí)現(xiàn)3個(gè)方法:onSurfaceCreated(, onSurfaceChanged( 和onDrawFrame(。這些方法很容易理解,第一個(gè)在surface創(chuàng)建以后調(diào)用,第二個(gè)是在surface發(fā)生改變以后調(diào)用,例如從豎屏切換到橫屏的時(shí)候,最后一個(gè)方法是當(dāng)任何時(shí)候調(diào)用一個(gè)畫(huà)圖方法的時(shí)候。從11行到13行,我們用浮點(diǎn)數(shù)來(lái)定義RGB顏色系統(tǒng)中的每一個(gè)顏色。在28行,我們通過(guò)g

10、lClearColor(方法為底色定義了顏色。底色是在我們能看到的所有東西的后面,所以所有在底色后面的東西都是不可見(jiàn)的。可以想象這種東西為濃霧,擋住了所有的東西。然后我們將要為之設(shè)置距離來(lái)show一下它怎么用的。那時(shí)候你就一定會(huì)明白它是怎么存在的了。為了讓顏色變化可見(jiàn),我們必須調(diào)用glClear(以及顏色緩沖的Mask來(lái)清空buffer,然后為我們的底色使用新的底色。為了能看到它在起作用,我們這里為MotionEvent創(chuàng)建一個(gè)response,使用它來(lái)改變顏色。首先在VortexRenderer中來(lái)創(chuàng)建一個(gè)設(shè)置顏色的函數(shù)。public void setColor(float r, float

11、 g, float b _red = r;_green = g;_blue = b;復(fù)制代碼下面是VortexView類(lèi)中創(chuàng)建的方法來(lái)處理MotionEvent。public boolean onTouchEvent(final MotionEvent event queueEvent(new Runnable( public void run( _renderer.setColor(event.getX( / getWidth(, event.getY( / getHeight(, 1.0f;return true;復(fù)制代碼我們創(chuàng)建了一個(gè)匿名的Runnable對(duì)象,這里的run(方法調(diào)用re

12、nderer中的setColor方法。這有會(huì)根據(jù)MotionEvent坐標(biāo)做一些小的計(jì)算?,F(xiàn)在我們已經(jīng)有了一個(gè)小小的程序來(lái)使用OpenGl來(lái)改變我們的背景色了。在德語(yǔ)中我們叫這種小case為“Mit Kanonen auf Spatzen schießen”,翻譯過(guò)來(lái)應(yīng)該是“你在車(chē)輪上打死了一只蒼蠅”。這說(shuō)的恰到好處,這只是一個(gè)最最最小的例子,要學(xué)習(xí)OpenGL,你現(xiàn)在要準(zhǔn)備更多更多的東西。這部分最后提一下OpenGL的文檔documentation for OpenGL 。這個(gè)東西雖然可用想不高,但是它最少是一個(gè)文檔。Eclipse工程源代碼在這里下載(原地址:V ortex Pa

13、rt I這里是幾個(gè)截圖: -這個(gè)系列的第二部分是關(guān)于如何添加一個(gè)三角形并可以旋轉(zhuǎn)它。第一件事情是初始化需要顯示的三角形。我們來(lái)在VortexRenderer類(lèi)中添加一個(gè)方法initTriangle(。/ new object variables we need/ a raw buffer to hold indicesprivate ShortBuffer _indexBuffer;/ a raw buffer to hold the verticesprivate FloatBuffer _vertexBuffer;private short _indicesArray = 0, 1, 2;

14、private int _nrOfVertices = 3;/ code snippedprivate void initTriangle( / float has 4 bytesByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4;vbb.order(ByteOrder.nativeOrder(;_vertexBuffer = vbb.asFloatBuffer(;/ short has 2 bytesByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices *

15、 2;ibb.order(ByteOrder.nativeOrder(;_indexBuffer = ibb.asShortBuffer(;float coords = -0.5f, -0.5f, 0f, / (x1, y1, z10.5f, -0.5f, 0f, / (x2, y2, z20f, 0.5f, 0f / (x3, y3, z3;_vertexBuffer.put(coords;_indexBuffer.put(_indicesArray;_vertexBuffer.position(0;_indexBuffer.position(0;復(fù)制代碼讓我們從新的對(duì)象變量開(kāi)始. _ver

16、texBuffer為我們的三角形保存坐標(biāo)._indexBuffer保存索引. _nrOfVertices變量定義需要多少個(gè)頂點(diǎn).對(duì)于一個(gè)三角形來(lái)說(shuō),一共需要三個(gè)頂點(diǎn).這個(gè)方法首先為這里兩個(gè)buffer分配必須的內(nèi)存(14-22行. 接下來(lái)我們定義一些坐標(biāo)(24-28行 后面的注釋對(duì)用途給予了說(shuō)明.在30行,我們將coords數(shù)組填充給_vertexBuffer . 同樣在31行將indices數(shù)組填充給_indexBuffer 。最后將兩個(gè)buffer都設(shè)置position為0.為了防止每次都對(duì)三角形進(jìn)行初始化,我們僅僅在onDrawFrame(之前的行數(shù)調(diào)用它一次。一個(gè)比較好的選擇就是在on

17、SurfaceCreated(函數(shù)中.Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config / preparationgl.glEnableClientState(GL10.GL_VERTEX_ARRAY;initTriangle(;復(fù)制代碼glEnableClientState( 設(shè)置OpenGL使用vertex數(shù)組來(lái)畫(huà)。這是很重要的,因?yàn)槿绻贿@么設(shè)置OpenGL不知道如何處理我們的數(shù)據(jù)。接下來(lái)我們就要初始化我們的三角形。為什么我們不需使用不同的buffer?在新的onDrawFrame(方法中我們必須添加一些新的Op

18、enGL調(diào)用。Overridepublic void onDrawFrame(GL10 gl / define the color we want to be displayed as the "clipping wall"gl.glClearColor(_red, _green, _blue, 1.0f;/ clear the color buffer to show the ClearColor we called above.gl.glClear(GL10.GL_COLOR_BUFFER_BIT;/ set the color of our elementgl.glC

19、olor4f(0.5f, 0f, 0f, 0.5f;/ define the vertices we want to drawgl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer;/ finally draw the verticesgl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer;復(fù)制代碼好,一步一步地看。glClearColor( 和glClear( 在教程I部分已經(jīng)提到過(guò)。在第10行使用glColor4f(r

20、ed, green, blue, alpha設(shè)置三角形為暗紅色.在第13行,我們使用glVertexPointer(初始化Vertex Pointer. 第一個(gè)參數(shù)是大小,也是頂點(diǎn)的維數(shù)。我們使用的是x,y,z三維坐標(biāo)。第二個(gè)參數(shù),GL_FLOAT定義buffer中使用的數(shù)據(jù)類(lèi)型。第三個(gè)變量是0,是因?yàn)槲覀兊淖鴺?biāo)是在數(shù)組中緊湊的排列的,沒(méi)有使用offset。最后哦胡第四個(gè)參數(shù)頂點(diǎn)緩沖。最后,glDrawElements(將所有這些元素畫(huà)出來(lái)。第一個(gè)參數(shù)定義了什么樣的圖元將被畫(huà)出來(lái)。第二個(gè)參數(shù)定義有多少個(gè)元素,第三個(gè)是indices使用的數(shù)據(jù)類(lèi)型。最后一個(gè)是繪制頂點(diǎn)使用的索引緩沖。當(dāng)最后測(cè)試這個(gè)

21、應(yīng)用的使用,你會(huì)看到一個(gè)在屏幕中間靜止的三角形。當(dāng)你點(diǎn)擊屏幕的時(shí)候,屏幕的背景顏色還是會(huì)改變。現(xiàn)在往里面添加對(duì)三角形的旋轉(zhuǎn)。下面的代碼是寫(xiě)在VortexRenderer類(lèi)中的.private float _angle;public void setAngle(float angle _angle = angle;復(fù)制代碼glRotatef(方法在glColor4f(之前被onDrawFrame(調(diào)用.Overridepublic void onDrawFrame(GL10 gl / set rotationgl.glRotatef(_angle, 0f, 1f, 0f;gl.glColor4f

22、(0.5f, 0f, 0f, 0.5f;/ code snipped復(fù)制代碼這時(shí)候我們可以繞y軸旋轉(zhuǎn)。如果需要改變只需要改變glRotate(方法中的0f。這個(gè)參數(shù)中的值表示一個(gè)向量,標(biāo)志三角形繞著旋轉(zhuǎn)的坐標(biāo)軸。要讓它可用,我們必須在V ortexView中的onTouchEvent(中添加一個(gè)調(diào)用。public boolean onTouchEvent(final MotionEvent event queueEvent(new Runnable( public void run( _renderer.setColor(event.getX( / getWidth(, event.getY(

23、 / getHeight(, 1.0f;_renderer.setAngle(event.getX( / 10;return true;復(fù)制代碼上面代碼中除以10是為了減小角度變換的速度。現(xiàn)在編譯運(yùn)行這個(gè)程序。如果你在屏幕的最左邊點(diǎn)擊,你會(huì)看到三角形輕微旋轉(zhuǎn)。如果你將手指移到右邊,旋轉(zhuǎn)的速度就會(huì)變得很快。Eclipse工程的源代碼在這里下載(原鏈接: V ortex Part II -在這個(gè)系列的第三部分給你show一下如何停止三角形的轉(zhuǎn)動(dòng),并告訴你原來(lái)的旋轉(zhuǎn)其實(shí)只是在三角形上進(jìn)行的旋轉(zhuǎn),而不是在攝像機(jī)“camera”上進(jìn)行的旋轉(zhuǎn)。我們希望能對(duì)旋轉(zhuǎn)進(jìn)行更多的控制。為此,在每次調(diào)用onDrawF

24、rame(方法的時(shí)候都會(huì)重置這個(gè)矩陣。這會(huì)重設(shè)三角形的角度以便其總是可以旋轉(zhuǎn)到給定的角度。Overridepublic void onDrawFrame(GL10 gl / define the color we want to be displayed as the "clipping wall"gl.glClearColor(_red, _green, _blue, 1.0f;/ reset the matrix - good to fix the rotation to a static anglegl.glLoadIdentity(;/ clear the colo

25、r buffer and the depth buffer to show the ClearColor/ we called above.gl.glClear(GL10.GL_COLOR_BUFFER_BIT;/ code snipped復(fù)制代碼在V ortexView類(lèi)中,你應(yīng)該刪除“除以10”以便其可以旋轉(zhuǎn)范圍更大一些。_renderer.setAngle(event.getX(;復(fù)制代碼如果嘗試了這些,你將會(huì)看到旋轉(zhuǎn)只會(huì)根據(jù)觸摸的到的位置來(lái)旋轉(zhuǎn)。如果沒(méi)有觸摸屏幕,旋轉(zhuǎn)不會(huì)發(fā)生改變。下一件事情:我們旋轉(zhuǎn)的是三角形本身,還是旋轉(zhuǎn)的view/camera?為了驗(yàn)證它,最簡(jiǎn)單的辦法是創(chuàng)建第二個(gè)

26、不旋轉(zhuǎn)的三角形進(jìn)行對(duì)照。最快也是最笨的辦法是copy&paste initTriangle(方法為一個(gè)新的方法initStaticTriangle(, copy&paste其中的兩個(gè)buffer,copy&paste并修改onDrawFrame(方法中的最后四行。不要忘記了改變第二個(gè)三角形的顏色以及改變第二個(gè)三角形的坐標(biāo),這樣方便我們能看到兩個(gè)三角形。我將每個(gè)地方的0.5f都改成了0.4f.這里是整個(gè)的類(lèi):package com.droidnova.android.games.vortex;import java.nio.ByteBuffer;import java.n

27、io.ByteOrder;import java.nio.FloatBuffer;import java.nio.ShortBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLSurfaceView;public class VortexRenderer implements GLSurfaceView.Renderer private static final String LOG_TAG =

28、 VortexRenderer.class.getSimpleName(;private float _red = 0f;private float _green = 0f;private float _blue = 0f;/ a raw buffer to hold indices allowing a reuse of points.private ShortBuffer _indexBuffer;private ShortBuffer _indexBufferStatic;/ a raw buffer to hold the verticesprivate FloatBuffer _ve

29、rtexBuffer;private FloatBuffer _vertexBufferStatic;private short _indicesArray = 0, 1, 2;private int _nrOfVertices = 3;private float _angle;Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config / preparationgl.glEnableClientState(GL10.GL_VERTEX_ARRAY;initTriangle(;initStaticTriangle(;Overri

30、depublic void onSurfaceChanged(GL10 gl, int w, int h gl.glViewport(0, 0, w, h;public void setAngle(float angle _angle = angle;Overridepublic void onDrawFrame(GL10 gl / define the color we want to be displayed as the "clipping wall"gl.glClearColor(_red, _green, _blue, 1.0f;/ reset the matri

31、x - good to fix the rotation to a static anglegl.glLoadIdentity(;/ clear the color buffer to show the ClearColor we called above.gl.glClear(GL10.GL_COLOR_BUFFER_BIT;/ draw the static trianglegl.glColor4f(0f, 0.5f, 0f, 0.5f;gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBufferStatic;gl.glDrawElements

32、(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBufferStatic;/ set rotation for the non-static trianglegl.glRotatef(_angle, 0f, 1f, 0f;gl.glColor4f(0.5f, 0f, 0f, 0.5f;gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer;gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UN

33、SIGNED_SHORT, _indexBuffer;private void initTriangle( / float has 4 bytesByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4; vbb.order(ByteOrder.nativeOrder(;_vertexBuffer = vbb.asFloatBuffer(;/ short has 4 bytesByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2;ibb.order(Byt

34、eOrder.nativeOrder(;_indexBuffer = ibb.asShortBuffer(;float coords = -0.5f, -0.5f, 0f, / (x1, y1, z10.5f, -0.5f, 0f, / (x2, y2, z20f, 0.5f, 0f / (x3, y3, z3;_vertexBuffer.put(coords;_indexBuffer.put(_indicesArray;_vertexBuffer.position(0;_indexBuffer.position(0;private void initStaticTriangle( / flo

35、at has 4 bytesByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4; vbb.order(ByteOrder.nativeOrder(;_vertexBufferStatic = vbb.asFloatBuffer(;/ short has 4 bytesByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2;ibb.order(ByteOrder.nativeOrder(;_indexBufferStatic = ibb.asShortB

36、uffer(;float coords = -0.4f, -0.4f, 0f, / (x1, y1, z10.4f, -0.4f, 0f, / (x2, y2, z20f, 0.4f, 0f / (x3, y3, z3;_vertexBufferStatic.put(coords;_indexBufferStatic.put(_indicesArray;_vertexBufferStatic.position(0;_indexBufferStatic.position(0;public void setColor(float r, float g, float b _red = r;_gree

37、n = g;_blue = b;復(fù)制代碼如果作了以上這些,你會(huì)看到只有一個(gè)三角形可以旋轉(zhuǎn)。如果你想兩個(gè)都可以旋轉(zhuǎn),只需要在“draw the static triangle”這個(gè)注釋的旁邊也給它加上一行代碼就可以了。編譯并運(yùn)行這個(gè)程序,你可以看到綠色的三角形在旋轉(zhuǎn),同時(shí)紅色的三角形還是呆在原來(lái)的地方。這也充分驗(yàn)證了我們的答案,我們旋轉(zhuǎn)的只是三角形而不是整個(gè)場(chǎng)景。Eclipse工程源代碼在這里下載: V ortex Part III -這個(gè)系列的第四部分講如何給三角形添加顏色。在上一部分我們創(chuàng)建了第二個(gè)靜態(tài)的三角形來(lái)驗(yàn)證我們旋轉(zhuǎn)的是三角形而不是整個(gè)場(chǎng)景。這里我們將這個(gè)靜態(tài)的三角形刪除掉。刪除掉i

38、nitStaticTriangle(函數(shù),刪除兩個(gè)buffer, _indexBufferStatic和_vertexBufferStatic。同時(shí)也要?jiǎng)h除原來(lái)初始靜止三角形時(shí)用到的onDrawFrame(中的最后四行。新的onDrawFrame(方法如下:Overridepublic void onDrawFrame(GL10 gl / define the color we want to be displayed as the "clipping wall"gl.glClearColor(_red, _green, _blue, 1.0f;/ reset the ma

39、trix - good to fix the rotation to a static anglegl.glLoadIdentity(;/ clear the color buffer to show the ClearColor we called above.gl.glClear(GL10.GL_COLOR_BUFFER_BIT;/ set rotation for the non-static trianglegl.glRotatef(_angle, 0f, 1f, 0f;gl.glColor4f(0.5f, 0f, 0f, 0.5f;gl.glVertexPointer(3, GL10

40、.GL_FLOAT, 0, _vertexBuffer;gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer;復(fù)制代碼現(xiàn)在我們?yōu)楸4骖伾畔?chuàng)建一個(gè)新的buffer。這個(gè)_colorBuffer是一個(gè)對(duì)象變量,但是我們需要在initTriangle(方法中定義顏色并填充這個(gè)buffer./ code snipped/ a raw buffer to hold the colorsprivate FloatBuffer _colorBuffer;/ code snipped

41、private void initTriangle( / float has 4 bytesByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4;vbb.order(ByteOrder.nativeOrder(;_vertexBuffer = vbb.asFloatBuffer(;/ short has 4 bytesByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2;ibb.order(ByteOrder.nativeOrder(;_indexBu

42、ffer = ibb.asShortBuffer(;/ float has 4 bytes, 4 colors (RGBA * number of vertices * 4 bytesByteBuffer cbb = ByteBuffer.allocateDirect(4 * _nrOfVertices * 4;cbb.order(ByteOrder.nativeOrder(;_colorBuffer = cbb.asFloatBuffer(;float coords = -0.5f, -0.5f, 0f, / (x1, y1, z10.5f, -0.5f, 0f, / (x2, y2, z2

43、0.5f, 0.5f, 0f / (x3, y3, z3;float colors = 1f, 0f, 0f, 1f, / point 10f, 1f, 0f, 1f, / point 20f, 0f, 1f, 1f, / point 3;_vertexBuffer.put(coords;_indexBuffer.put(_indicesArray;_colorBuffer.put(colors;_vertexBuffer.position(0;_indexBuffer.position(0;_colorBuffer.position(0;復(fù)制代碼我們創(chuàng)建了一個(gè)FloatBuffer類(lèi)型的對(duì)象

44、變量_colorBuffer(第四行。在initTriangle(方法中我們?yōu)樾碌念伾玝uffer分配了足夠多的內(nèi)存(19-21行。接下來(lái)我們創(chuàng)建了一個(gè)float數(shù)組(23-27行,每個(gè)頂點(diǎn)有4個(gè)值。這個(gè)結(jié)構(gòu)是RGBA(Red,Green,Blue,alpha的,所以第一個(gè)頂點(diǎn)是紅顏色,第二個(gè)顏色是綠色,第三個(gè)顏色是藍(lán)色。最后兩部和_vertexBuffer 相同。我們將顏色數(shù)組放到buffer里面,將buffer的position設(shè)置為0.當(dāng)這些準(zhǔn)備工作都做完了以后,我們開(kāi)始告訴OpenGL ES使用我們的顏色數(shù)組。這通過(guò)glEnableClientState(,以及glColorPoint

45、er(來(lái)完成,和vertexBuffer類(lèi)似。Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config / preparationgl.glEnableClientState(GL10.GL_VERTEX_ARRAY;gl.glEnableClientState(GL10.GL_COLOR_ARRAY;initTriangle(;/ code snippedOverridepublic void onDrawFrame(GL10 gl / code snipped/ gl.glColor4f(0.5f, 0f, 0f, 0.5

46、f;gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer;gl.glColorPointer(4, GL10.GL_FLOAT, 0, _colorBuffer;gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer;復(fù)制代碼第五行我們enable了color mode。在17行我們?cè)O(shè)置了顏色pointer。參數(shù)4表示RGBA(RGBA 剛好是四個(gè)值,其余的幾個(gè)參數(shù)大家都比較熟悉了。也許你也看到了,我們注釋掉了15行,因

47、為我們使用的是color mode,所以不再需要glColor4f。它會(huì)覆蓋,所以我們可以注注釋掉或者刪除掉他。Eclipse工程源代碼參考: V ortex Part IV -系列的第五部分講如果創(chuàng)建你的第一個(gè)完整的3D對(duì)象。這個(gè)case中是一個(gè)4面的金字塔。為了讓我們接下來(lái)的開(kāi)發(fā)更容易,這里需要做一些準(zhǔn)備。我們必須將計(jì)算buffer以及創(chuàng)建數(shù)組時(shí)的大變得更加動(dòng)態(tài)。private int _nrOfVertices = 0;private void initTriangle( float coords = / coodinates;_nrOfVertices = coords.length;

48、float colors = / colors;short indices = new short / indices;/ float has 4 bytes, coordinate * 4 bytesByteBuffer vbb = ByteBuffer.allocateDirect(coords.length * 4;vbb.order(ByteOrder.nativeOrder(;_vertexBuffer = vbb.asFloatBuffer(;/ short has 2 bytes, indices * 2 bytesByteBuffer ibb = ByteBuffer.allo

49、cateDirect(indices.length * 2;ibb.order(ByteOrder.nativeOrder(;_indexBuffer = ibb.asShortBuffer(;/ float has 4 bytes, colors (RGBA * 4 bytesByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4;cbb.order(ByteOrder.nativeOrder(;_colorBuffer = cbb.asFloatBuffer(;_vertexBuffer.put(coords;_indexB

50、uffer.put(indices;_colorBuffer.put(colors;_vertexBuffer.position(0;_indexBuffer.position(0;_colorBuffer.position(0;復(fù)制代碼為了更加的動(dòng)態(tài),我們必須改變一些變量以便我們接下來(lái)的工作。讓我們來(lái)細(xì)看一下:在第一行你可以看到,我們初始化_nrOfV ertices為0,因?yàn)槲覀兛梢栽诘谄咝心抢锿ㄟ^(guò)坐標(biāo)的大小來(lái)確定它。我們同時(shí)也將_indecesArray改為局部變量indices,并在13行進(jìn)行了初始化。這個(gè)buffer創(chuàng)建過(guò)程被放在了坐標(biāo)、顏色以及頂點(diǎn)數(shù)組的下邊,因?yàn)閎uffer大小取

51、決于數(shù)組。所以請(qǐng)看17-18行,22-23行,27-28行。在注釋里面我解釋了計(jì)算方法。主要的好處是,我們可以創(chuàng)建更多的vertices,而不用手動(dòng)重新計(jì)算有多少個(gè)vertices,以及數(shù)組和buffer的大小。下一步:你需要明白OpenGL如何繪制并決定我們看到的東西。相對(duì)于OpenGL來(lái)說(shuō)OpenGL ES一個(gè)很大的缺點(diǎn)就是除了三角形以外沒(méi)有別的圖元類(lèi)型。我們沒(méi)有其它多邊形,所以我們想要?jiǎng)?chuàng)建的所有的對(duì)象都必須由三角形構(gòu)成。我引用一個(gè)blog的帖子來(lái)說(shuō)明這個(gè)問(wèn)題:IPhone developer ,同時(shí)也推薦他的這些文章OpenGL ES series.這里有更多的關(guān)于三角形的東西你需要知道

52、。在OpenGL中,有一個(gè)概念叫做彎曲(winding,意思是vertices繪制時(shí)的順序。與現(xiàn)實(shí)世界中的對(duì)象不同,OpenGL中的多邊形一般沒(méi)有兩個(gè)面。他們只有一個(gè)面,一般是正面,一個(gè)三角形只有當(dāng)其正面面對(duì)觀(guān)察者的時(shí)候才可以被看到??梢耘渲肙penGL將一個(gè)多邊形作為兩面的,但是默認(rèn)情況下三角形只有一個(gè)可見(jiàn)的面。知道了那邊是多邊形的正面以后,OpenGL就可以少做一半的計(jì)算量。如果設(shè)置兩面都可視,則需要多的計(jì)算。雖然有時(shí)候一個(gè)多邊形會(huì)獨(dú)立地顯示,但是你或許不是非常需要它的背面顯示,經(jīng)常一個(gè)三角形是一個(gè)更大的對(duì)象的一部分,多邊形的一面將在這個(gè)物體的內(nèi)部,所以永遠(yuǎn)也不會(huì)被看到。這個(gè)沒(méi)有被顯示的一

53、面被稱(chēng)作背面,OpenGl通過(guò)繪制的順序來(lái)確定那個(gè)面是正面哪個(gè)是背面。頂點(diǎn)按照逆時(shí)針繪制的是正面(默認(rèn)是這樣,但是可以被改變。因?yàn)镺penGL 能很容易地確定哪些三角形對(duì)用戶(hù)是可視的,它就可以通過(guò)使用Backface Culling來(lái)避免為那些不顯示在前面的多邊形做無(wú)用功。我們將在下一篇文章里討論視角的問(wèn)題,但是你現(xiàn)在可以想象它為一個(gè)虛擬攝像機(jī),或者通過(guò)一個(gè)虛擬的窗口來(lái)觀(guān)察OpenGL的世界。 在上面的示意圖中,左邊青綠色的的三角形是背面,將不會(huì)被繪制,因?yàn)樗鄬?duì)于觀(guān)察者來(lái)說(shuō)是順時(shí)針的。而在右邊的這個(gè)三角形是正面,將會(huì)被繪制,因?yàn)槔L制頂點(diǎn)的順序相對(duì)于觀(guān)察者來(lái)說(shuō)是逆時(shí)針的。因?yàn)槲覀兿胱龅氖莿?chuàng)建一

54、個(gè)漂亮的金字塔,我們首先disable這個(gè)glClearColor(。我們可以刪除掉變量_red, _green, _blue,還有方法setColor(. 我們也想改變視角,所以我們將旋轉(zhuǎn)分的x和y軸上。public class VortexRenderer implements GLSurfaceView.Renderer private static final String LOG_TAG = VortexRenderer.class.getSimpleName(;/ a raw buffer to hold indices allowing a reuse of points.pri

55、vate ShortBuffer _indexBuffer;/ a raw buffer to hold the verticesprivate FloatBuffer _vertexBuffer;/ a raw buffer to hold the colorsprivate FloatBuffer _colorBuffer;private int _nrOfVertices = 0;private float _xAngle;private float _yAngle;Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config / code snippedOverridepublic void onSurfaceChanged(GL10 gl, int w, int h gl.glViewport(0, 0, w, h;public void setXAngle(float angle

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論