版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、安卓3D游戲開發(fā)教程本帖最后由huzht 于2010-4-25 07:58 編輯這幾篇Android 3D游戲開發(fā)的文章原文出自一位德國(guó)人Martin 在寫的文章,有l(wèi)ixinso翻譯為中文。第一部分首先介紹OpenGL相關(guān)的術(shù)語,并引導(dǎo)你開始3D開發(fā)的第一步。這個(gè)關(guān)于3D游戲的系列的叫做V ortex .這個(gè)教程主要focus在3D編程上,其他的東西比如菜單和程序生命周期雖然是代碼的一部分,但是在這里不會(huì)被提到。首先開始介紹OpenGL的術(shù)語。頂點(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)閃一般都是被用來作為占位符。vertex的復(fù)數(shù)是vertices(這對(duì)非英語母語的人來說比較重要,因?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)來創(chuàng)建一個(gè)三角形。多邊形Polygon多邊形是至少有3個(gè)連接著的點(diǎn)組成的一個(gè)對(duì)象。三角形也是一個(gè)多邊形。圖元Primitives一個(gè)Primitive是一個(gè)三維的對(duì)象,使用三角形或者多邊形創(chuàng)建。形象的說,一個(gè)有500
3、00個(gè)頂點(diǎn)的非常精細(xì)的模型是一個(gè)Primitive,同樣一個(gè)只有500個(gè)頂點(diǎn)的低模也叫做一個(gè)Primitive?,F(xiàn)在我們可以開始變成了。創(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類。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ì)幫助我們畫3D圖像。接下來看V ortexRenderer類。一個(gè)Renderer包含畫一幀所必需的所有東西。引用自這兒references 。Renderer負(fù)責(zé)OpenGL call來render一個(gè)幀。來看一下這個(gè)類: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è)畫圖方法的時(shí)候。從11行到13行,我們用浮點(diǎn)數(shù)來定義RGB顏色系統(tǒng)中的每一個(gè)顏色。在28行,我們通過g
10、lClearColor(方法為底色定義了顏色。底色是在我們能看到的所有東西的后面,所以所有在底色后面的東西都是不可見的??梢韵胂筮@種東西為濃霧,擋住了所有的東西。然后我們將要為之設(shè)置距離來show一下它怎么用的。那時(shí)候你就一定會(huì)明白它是怎么存在的了。為了讓顏色變化可見,我們必須調(diào)用glClear(以及顏色緩沖的Mask來清空buffer,然后為我們的底色使用新的底色。為了能看到它在起作用,我們這里為MotionEvent創(chuàng)建一個(gè)response,使用它來改變顏色。首先在VortexRenderer中來創(chuàng)建一個(gè)設(shè)置顏色的函數(shù)。public void setColor(float r, float
11、 g, float b _red = r;_green = g;_blue = b;復(fù)制代碼下面是VortexView類中創(chuàng)建的方法來處理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è)小小的程序來使用OpenGl來改變我們的背景色了。在德語中我們叫這種小case為“Mit Kanonen auf Spatzen schießen”,翻譯過來應(yīng)該是“你在車輪上打死了一只蒼蠅”。這說的恰到好處,這只是一個(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)它。第一件事情是初始化需要顯示的三角形。我們來在VortexRenderer類中添加一個(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ì)象變量開始. _ver
16、texBuffer為我們的三角形保存坐標(biāo)._indexBuffer保存索引. _nrOfVertices變量定義需要多少個(gè)頂點(diǎn).對(duì)于一個(gè)三角形來說,一共需要三個(gè)頂點(diǎn).這個(gè)方法首先為這里兩個(gè)buffer分配必須的內(nèi)存(14-22行. 接下來我們定義一些坐標(biāo)(24-28行 后面的注釋對(duì)用途給予了說明.在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ù)組來畫。這是很重要的,因?yàn)槿绻贿@么設(shè)置OpenGL不知道如何處理我們的數(shù)據(jù)。接下來我們就要初始化我們的三角形。為什么我們不需使用不同的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)提到過。在第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ù)類型。第三個(gè)變量是0,是因?yàn)槲覀兊淖鴺?biāo)是在數(shù)組中緊湊的排列的,沒有使用offset。最后哦胡第四個(gè)參數(shù)頂點(diǎn)緩沖。最后,glDrawElements(將所有這些元素畫出來。第一個(gè)參數(shù)定義了什么樣的圖元將被畫出來。第二個(gè)參數(shù)定義有多少個(gè)元素,第三個(gè)是indices使用的數(shù)據(jù)類型。最后一個(gè)是繪制頂點(diǎn)使用的索引緩沖。當(dāng)最后測(cè)試這個(gè)
21、應(yīng)用的使用,你會(huì)看到一個(gè)在屏幕中間靜止的三角形。當(dāng)你點(diǎn)擊屏幕的時(shí)候,屏幕的背景顏色還是會(huì)改變。現(xiàn)在往里面添加對(duì)三角形的旋轉(zhuǎn)。下面的代碼是寫在VortexRenderer類中的.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是為了減小角度變換的速度?,F(xiàn)在編譯運(yùn)行這個(gè)程序。如果你在屏幕的最左邊點(diǎn)擊,你會(huì)看到三角形輕微旋轉(zhuǎn)。如果你將手指移到右邊,旋轉(zhuǎn)的速度就會(huì)變得很快。Eclipse工程的源代碼在這里下載(原鏈接: V ortex Part II -在這個(gè)系列的第三部分給你show一下如何停止三角形的轉(zhuǎn)動(dòng),并告訴你原來的旋轉(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類中,你應(yīng)該刪除“除以10”以便其可以旋轉(zhuǎn)范圍更大一些。_renderer.setAngle(event.getX(;復(fù)制代碼如果嘗試了這些,你將會(huì)看到旋轉(zhuǎn)只會(huì)根據(jù)觸摸的到的位置來旋轉(zhuǎn)。如果沒有觸摸屏幕,旋轉(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è)的類: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í)紅色的三角形還是呆在原來的地方。這也充分驗(yàn)證了我們的答案,我們旋轉(zhuǎn)的只是三角形而不是整個(gè)場(chǎng)景。Eclipse工程源代碼在這里下載: V ortex Part III -這個(gè)系列的第四部分講如何給三角形添加顏色。在上一部分我們創(chuàng)建了第二個(gè)靜態(tài)的三角形來驗(yàn)證我們旋轉(zhuǎn)的是三角形而不是整個(gè)場(chǎng)景。這里我們將這個(gè)靜態(tài)的三角形刪除掉。刪除掉i
38、nitStaticTriangle(函數(shù),刪除兩個(gè)buffer, _indexBufferStatic和_vertexBufferStatic。同時(shí)也要?jiǎng)h除原來初始靜止三角形時(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類型的對(duì)象
44、變量_colorBuffer(第四行。在initTriangle(方法中我們?yōu)樾碌念伾玝uffer分配了足夠多的內(nèi)存(19-21行。接下來我們創(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)備工作都做完了以后,我們開始告訴OpenGL ES使用我們的顏色數(shù)組。這通過glEnableClientState(,以及glColorPoint
45、er(來完成,和vertexBuffer類似。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面的金字塔。為了讓我們接下來的開發(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),我們必須改變一些變量以便我們接下來的工作。讓我們來細(xì)看一下:在第一行你可以看到,我們初始化_nrOfV ertices為0,因?yàn)槲覀兛梢栽诘谄咝心抢锿ㄟ^坐標(biāo)的大小來確定它。我們同時(shí)也將_indecesArray改為局部變量indices,并在13行進(jìn)行了初始化。這個(gè)buffer創(chuàng)建過程被放在了坐標(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來說OpenGL ES一個(gè)很大的缺點(diǎn)就是除了三角形以外沒有別的圖元類型。我們沒有其它多邊形,所以我們想要?jiǎng)?chuàng)建的所有的對(duì)象都必須由三角形構(gòu)成。我引用一個(gè)blog的帖子來說明這個(gè)問題:IPhone developer ,同時(shí)也推薦他的這些文章OpenGL ES series.這里有更多的關(guān)于三角形的東西你需要知道
52、。在OpenGL中,有一個(gè)概念叫做彎曲(winding,意思是vertices繪制時(shí)的順序。與現(xiàn)實(shí)世界中的對(duì)象不同,OpenGL中的多邊形一般沒有兩個(gè)面。他們只有一個(gè)面,一般是正面,一個(gè)三角形只有當(dāng)其正面面對(duì)觀察者的時(shí)候才可以被看到??梢耘渲肙penGL將一個(gè)多邊形作為兩面的,但是默認(rèn)情況下三角形只有一個(gè)可見的面。知道了那邊是多邊形的正面以后,OpenGL就可以少做一半的計(jì)算量。如果設(shè)置兩面都可視,則需要多的計(jì)算。雖然有時(shí)候一個(gè)多邊形會(huì)獨(dú)立地顯示,但是你或許不是非常需要它的背面顯示,經(jīng)常一個(gè)三角形是一個(gè)更大的對(duì)象的一部分,多邊形的一面將在這個(gè)物體的內(nèi)部,所以永遠(yuǎn)也不會(huì)被看到。這個(gè)沒有被顯示的一
53、面被稱作背面,OpenGl通過繪制的順序來確定那個(gè)面是正面哪個(gè)是背面。頂點(diǎn)按照逆時(shí)針繪制的是正面(默認(rèn)是這樣,但是可以被改變。因?yàn)镺penGL 能很容易地確定哪些三角形對(duì)用戶是可視的,它就可以通過使用Backface Culling來避免為那些不顯示在前面的多邊形做無用功。我們將在下一篇文章里討論視角的問題,但是你現(xiàn)在可以想象它為一個(gè)虛擬攝像機(jī),或者通過一個(gè)虛擬的窗口來觀察OpenGL的世界。 在上面的示意圖中,左邊青綠色的的三角形是背面,將不會(huì)被繪制,因?yàn)樗鄬?duì)于觀察者來說是順時(shí)針的。而在右邊的這個(gè)三角形是正面,將會(huì)被繪制,因?yàn)槔L制頂點(diǎn)的順序相對(duì)于觀察者來說是逆時(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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2023年四川省成都市公開招聘警務(wù)輔助人員輔警筆試自考題1卷含答案
- 2023年甘肅省酒泉市公開招聘警務(wù)輔助人員輔警筆試自考題2卷含答案
- 2024年湖北省孝感市公開招聘警務(wù)輔助人員輔警筆試自考題2卷含答案
- 2022年青海省西寧市公開招聘警務(wù)輔助人員輔警筆試自考題1卷含答案
- 2024年廣東省韶關(guān)市公開招聘警務(wù)輔助人員輔警筆試自考題1卷含答案
- 頒獎(jiǎng)晚會(huì)發(fā)言稿
- 個(gè)人借條范本整合
- 霸氣押韻的班級(jí)口號(hào)
- 湖北省省直轄行政單位(2024年-2025年小學(xué)六年級(jí)語文)部編版質(zhì)量測(cè)試(下學(xué)期)試卷及答案
- 廣東省陽江市(2024年-2025年小學(xué)六年級(jí)語文)部編版階段練習(xí)(上學(xué)期)試卷及答案
- 《基因突變的機(jī)制》課件
- 天安門地區(qū)地下空間開發(fā)利用策略-洞察分析
- 《基層管理者職業(yè)素養(yǎng)與行為規(guī)范》考核試題及答案
- 公共關(guān)系理論與實(shí)務(wù)教程 課件 項(xiàng)目九-公共關(guān)系危機(jī)管理
- 椎間孔鏡治療腰椎間盤突出
- 2024年融媒體中心事業(yè)單位考試招考142人500題大全加解析答案
- 2024-2025學(xué)年 語文二年級(jí)上冊(cè)統(tǒng)編版期末測(cè)試卷(含答案)
- 期末測(cè)試題二(含答案)2024-2025學(xué)年譯林版七年級(jí)英語上冊(cè)
- 大創(chuàng)賽項(xiàng)目書
- 產(chǎn)品質(zhì)量知識(shí)培訓(xùn)課件
- 乳腺旋切手術(shù)
評(píng)論
0/150
提交評(píng)論