在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ 基本幾何圖形定義
繪制線段 Line Segment
投影變換 Projection
繪制迷你太陽系
繪制一個球體
繪制三角形 Triangle
OpenGL 光照模型
三維坐標(biāo)系及坐標(biāo)變換初步
定義 3D 模型的前面和后面
繪制一個 20 面體
顏色 Color
Depth Buffer
材質(zhì)及光照示例
基本幾何圖形定義
關(guān)于EGL
導(dǎo)言
Viewing 和 Modeling(MODELVIEW) 變換
FrameBuffer
設(shè)置光照效果 Set Lighting
Viewport 變換
階段小結(jié)
繪制點(diǎn) Point
OpenGL ES API 命名習(xí)慣
通用的矩陣變換指令
關(guān)于 OpenGL ES
創(chuàng)建實例應(yīng)用 OpenGLDemos 程序框架
OpenGL ES 管道(Pipeline)
GLSurfaceView

基本幾何圖形定義

在前面 Android OpenGL ES 開發(fā)教程(7):創(chuàng)建實例應(yīng)用 OpenGLDemos 程序框架 我們創(chuàng)建了示例程序的基本框架,并提供了一個 “Hello World” 示例,將屏幕顯示為紅色。

本例介紹 OpenGL ES 3D 圖形庫支持的幾種基本幾何圖形,本篇部分內(nèi)容與 Android OpenGL ES 簡明開發(fā)教程三:3D 繪圖基本概念 類似。

通常二維圖形庫可以繪制點(diǎn),線,多邊形,圓弧,路徑等等。OpenGL ES 支持繪制的基本幾何圖形分為三類:點(diǎn),線段,三角形。也就是說 OpenGL ES 只能繪制這三種基本幾何圖形。任何復(fù)雜的2D或是3D圖形都是通過這三種幾何圖形構(gòu)造而成的。

比如下圖復(fù)雜的 3D 圖形,都有將其分割成細(xì)小的三角形面而構(gòu)成的。然后通過上色 (Color),添加材質(zhì) (Texture),再添加光照(lighting),構(gòu)造3D效果的圖形:

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/46.png" alt="" />

點(diǎn),線段,三角形都是通過頂點(diǎn)來定義的,也就是頂點(diǎn)數(shù)組來定義。對應(yīng)平面上的一系列頂點(diǎn),可以看出一個個孤立的點(diǎn) (Point),也可以兩個兩個連接成線段 (Line Segment) ,也可以三個三個連成三角形 (Triangle)。這些對一組頂點(diǎn)的不同解釋就定義了 Android OpenGL ES 可以繪制的基本幾何圖形,下面定義了 OpenGL ES 定義的幾種模式:

GL_POINTS

繪制獨(dú)立的點(diǎn)。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/47.png" alt="" />

GL_LINE_STRIP

繪制一系列線段。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/48.png" alt="" />

GL_LINE_LOOP

類同上,但是首尾相連,構(gòu)成一個封閉曲線。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/49.png" alt="" />

GL_LINES

頂點(diǎn)兩兩連接,為多條線段構(gòu)成。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/50.png" alt="" />

GL_TRIANGLES

每隔三個頂點(diǎn)構(gòu)成一個三角形,為多個三角形組成。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/51.png" alt="" />

GL_TRIANGLE_STRIP

每相鄰三個頂點(diǎn)組成一個三角形,為一系列相接三角形構(gòu)成。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/52.png" alt="" />

GL_TRIANGLE_FAN

以一個點(diǎn)為三角形公共頂點(diǎn),組成一系列相鄰的三角形。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/53.png" alt="" />

以上模式對應(yīng)到 Android 渲染方法:

OpenGL ES 提供了兩類方法來繪制一個空間幾何圖形:

  • public abstract void glDrawArrays(int mode, int first, int count) 使用 VetexBuffer 來繪制,頂點(diǎn)的順序由 vertexBuffer 中的順序指定。
  • public abstract void glDrawElements(int mode, int count, int type, Buffer indices) ,可以重新定義頂點(diǎn)的順序,頂點(diǎn)的順序由 indices Buffer 指定。

其中 mode 為上述解釋頂點(diǎn)的模式。

前面說過頂點(diǎn)一般使用數(shù)組來定義,并使用 Buffer 來存儲以提高繪圖性能,參見Android OpenGL ES 開發(fā)中的Buffer使用

如下面定義三個頂點(diǎn)坐標(biāo),并把它們存放在 FloatBuffer 中:

float[] vertexArray = new float[]{
 -0.8f , -0.4f * 1.732f , 0.0f ,
 0.8f , -0.4f * 1.732f , 0.0f ,
 0.0f , 0.4f * 1.732f , 0.0f ,
 };
ByteBuffer vbb
 = ByteBuffer.allocateDirect(vertexArray.length*4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertex = vbb.asFloatBuffer();
vertex.put(vertexArray);
vertex.position(0);  

有了頂點(diǎn)的定義,下面就可以通過打開 OpenGL ES 管道(Pipeline)的相應(yīng)開關(guān)將頂點(diǎn)參數(shù)傳給 OpenGL 庫:

打開頂點(diǎn)開關(guān)和關(guān)閉頂點(diǎn)開關(guān)的方法如下:

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

在打開頂點(diǎn)開關(guān)后,將頂點(diǎn)坐標(biāo)傳給 OpenGL 管道的方法為:glVertexPointer:

public void glVertexPointer(int size,int type,int stride,Buffer pointer)
  • size:每個頂點(diǎn)坐標(biāo)維數(shù),可以為2,3,4。
  • type:頂點(diǎn)的數(shù)據(jù)類型,可以為 GL_BYTE, GL_SHORT, GL_FIXED,或 GL_FLOAT,缺省為浮點(diǎn)類型 GL_FLOAT。
  • stride:每個相鄰頂點(diǎn)之間在數(shù)組中的間隔(字節(jié)數(shù)),缺省為 0,表示頂點(diǎn)存儲之間無間隔。
  • pointer:存儲頂點(diǎn)的數(shù)組。

應(yīng)用用上可以般頂點(diǎn)的顏色值存放在對應(yīng)頂點(diǎn)后面,如下圖,RGB 采用 4 字節(jié)表示,此時相鄰頂點(diǎn)就不是連續(xù)存放的,stride 值為 4 。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/54.png" alt="" />

對應(yīng)頂點(diǎn)除了可以為其定義坐標(biāo)外,還可以指定顏色,材質(zhì),法線(用于光照處理)等。

glEnableClientState 和 glDisableClientState 可以控制的 pipeline 開關(guān)可以有:GL_COLOR_ARRAY (顏色),GL_NORMAL_ARRAY (法線),GL_TEXTURE_COORD_ARRAY (材質(zhì)),GL_VERTEX_ARRAY(頂點(diǎn)), GL_POINT_SIZE_ARRAY_OES等。

對應(yīng)的傳入顏色,頂點(diǎn),材質(zhì),法線的方法如下:

glColorPointer(int size,int type,int stride,Buffer pointer)
glVertexPointer(int size, int type, int stride, Buffer pointer)
glTexCoordPointer(int size, int type, int stride, Buffer pointer)
glNormalPointer(int type, int stride, Buffer pointer)

如果需要使用三角形來構(gòu)造復(fù)雜圖形,可以使用 GL_TRIANGLE_STRIP 或 GL_TRIANGLE_FAN 模式,另外一種是通過定義頂點(diǎn)序列:

如下圖定義了一個正方形:

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/55.png" alt="" />

對應(yīng)的頂點(diǎn)和 buffer 定義代碼:

private short[] indices = { 0, 1, 2, 0, 2, 3 };
//To gain some performance we also put this ones in a byte buffer.
// short is 2 bytes, therefore we multiply the number if vertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
ShortBuffer indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);  

定義三角形的頂點(diǎn)的順序很重要 在拼接曲面的時候,用來定義面的頂點(diǎn)的順序非常重要,因為頂點(diǎn)的順序定義了面的朝向(前向或是后向),為了獲取繪制的高性能,一般情況不會繪制面的前面和后面,只繪制面的“前面”。雖然“前面”“后面”的定義可以應(yīng)人而易,但一般為所有的“前面”定義統(tǒng)一的頂點(diǎn)順序(順時針或是逆時針方向)。

下面代碼設(shè)置逆時針方法為面的“前面”:

gl.glFrontFace(GL10.GL_CCW);  

打開 忽略“后面”設(shè)置:

gl.glEnable(GL10.GL_CULL_FACE);  

明確指明“忽略“哪個面的代碼如下:

gl.glCullFace(GL10.GL_BACK);  
上一篇:繪制一個 20 面體下一篇:導(dǎo)言