Android OpenGL教程-第二課【轉】


第二課 你的第一個多邊形:

 

在第一個教程的基礎上,我們添加了一個三角形和一個四邊形。也許你認為這很簡單,但你已經邁出了一大步,要知道任何在OpenGL中繪制的模型都會被分解為這兩種簡單的圖形。

讀完了這一課,你會學到如何在空間放置模型,並且會知道深度緩存的概念。

 

其他類不變,只更改OpenGLRenderer類。

首先,我們畫一個三角形,主要是在OnDrawFrame里面畫,使用的函數是

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

或者

gl.glDrawElements(GL10.GL_TRIANGLES, 3, GL10.GL_FLOAT, mIndexBuffer);

我們先使用drawArray,drawElement里面要多用一個indexBuffer。

 

第一步,定義個array

private float[] mTriangleArray = { 
        0f, 1f, 0f,   // 是上頂點
        -1f, -1f, 0f, // 左下頂點
        1f, -1f, 0f   // 右下頂點
};

這里實際上是定義了三角形的三個頂點,三個數分別是x,y,z的坐標,和數學里直角坐標系相同

     0f,  1f,   0f   是上頂點

    -1f, -1f,  0f   是左下頂點

     1f,  -1f,  0f   是右下頂點

 

定義個FloatBuffer,這是android畫三角形必須的結構

private FloatBuffer mTriangleBuffer;

來一個函數轉換array到Buffer

我們直接上一個工具類

 

BufferUtil類:

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

public class BufferUtil {
    public static FloatBuffer mBuffer;

    public static FloatBuffer floatToBuffer(float[] a) {
        // 先初始化buffer,數組的長度*4,因為一個float占4個字節
        ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
        // 數組排序用nativeOrder
        mbb.order(ByteOrder.nativeOrder());
        mBuffer = mbb.asFloatBuffer();
        mBuffer.put(a);
        mBuffer.position(0);
        return mBuffer;
    }
}

注意:這里有個排序的問題,是使用大端(BIG_ENDIAN)還是用小端(LITTLE_ENDIAN),在android里面,opengl畫圖must use native order direct buffer,否則報錯為ERROR/AndroidRuntime(6897): java.lang.IllegalArgumentException: Must use a native order direct Buffer這個錯誤在android1.6以上會出現,在1.5上不會出現。

這里我們直接使用allocateDirect和nativeOrder,就能滿足android的要求

第二步:

SurfaceCreate里面構建這個Buffer

mTriangleBuffer = BufferUtil.floatToBuffer(mTriangleArray);

第三步:

OndrawFrame里面畫三角形

// 利用數組模型來畫模型,要加此句(原文中沒有)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

// 三角形的顏色為紅色,透明度為不透明
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);

// 設置頂點,第一個參數是坐標的維數,這里是3維,第二個參數,表示buffer里面放的是float,第三個參數是0,
// 是因為我們的坐標在數組中是緊湊的排列的,沒有使用offset,最后的參數放的是存放頂點坐標的buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleBuffer);

// 畫數組,第一個參數表示畫三角形,第二個參數是first,第三個參數是count,表示在buffer里面的坐標的開始和個數
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

運行,會看到一個大三角形

 

下面,我們來變換坐標軸,畫個小三角形,原理就是把坐標軸向遠拉,意思就是讓鏡頭向后拉,這樣三角形就小了。

第一步:

在onSurfaceChanged(原文是OnSurfaceCreate,有錯誤)里面加入下面幾行代碼

float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

這幾行為透視圖設置屏幕。意味着越遠的東西看起來越小。這么做創建了一個現實外觀的場景。此處透視按照基於窗口寬度和高度的45度視角來計算。0.1f,100.0f是我們在場景中所能繪制深度的起點和終點。

gl.glMatrixMode(GL10.GL_PROJECTION);指明接下來的兩行代碼將影響projection matrix(投影矩陣)。投影矩陣負責為我們的場景增加透視。 

glLoadIdentity()近似於重置。它將所選的矩陣狀態恢復成其原始狀態。調用 glLoadIdentity()之后我們為場景設置透視圖。

glMatrixMode(GL_MODELVIEW)指明任何新的變換將會影響 modelview matrix(模型觀察矩陣)。模型觀察矩陣中存放了我們的物體訊息。最后我們重置模型觀察矩陣。如果您還不能理解這些術語的含義,請別着急。在以后的教程里,我會向大家解釋。只要知道如果您想獲得一個精彩的透視場景的話,必須這么做。

第二步:

OndrawFrame里面增加代碼如下:

gl.glMatrixMode(GL10.GL_MODELVIEW);
// 重置當前的模型觀察矩陣。
gl.glLoadIdentity();
// 沿着X軸左移1.5個單位,Y軸不動(0.0f),最后移入屏幕6.0f個單位
gl.glTranslatef(-1.5f, 0.0f, -6.0f);

當您調用glLoadIdentity()之后,您實際上將當前點移到了屏幕中心,X坐標軸從左至右,Y坐標軸從下至上,Z坐標軸從里至外。OpenGL屏幕中心的坐標值是X和Y軸上的0.0f點。中心左面的坐標值是負值,右面是正值。移向屏幕頂端是正值,移向屏幕底端是負值。移入屏幕深處是負值,移出屏幕則是正值。

glTranslatef(x, y, z)沿着 X, Y 和 Z 軸移動。根據前面的次序,下面的代碼沿着X軸左移1.5個單位,Y軸不動(0.0f),最后移入屏幕6.0f個單位。注意在glTranslatef(x, y, z)中當您移動的時候,您並不是相對屏幕中心移動,而是相對與當前所在的屏幕位置。

這時候就能畫出個小三角形了。

 

 

 

下面,我們來畫一個四邊形

四邊形的頂點數組為:

// 四邊形的頂點數組
private float[] mQuadsArray = { 
        1f, 1f, 0f, // 右上
        -1f, 1f, 0f, // 左上
        -1f, -1f, 0f, // 左下
        1f, -1f, 0f // 右下
}; // 從這里可以看出,我們按照逆時針的方向畫圖
private FloatBuffer mQuadsBuffer;

 

OnDrawFrame里面添加代碼

gl.glLoadIdentity();
// 坐標向右移1.5個單位
gl.glTranslatef(1.5f, 0.0f, -6.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mQuadsBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4); // 畫四邊形

在onSurfaceCreated里面添加代碼

mQuadsBuffer = BufferUtil.floatToBuffer(mQuadsArray);

 

第一個參數是繪圖模式,而且你現在看到兩種可能的OpenGL繪圖方式。 我想花時間來討論現在不同的繪圖模式。

它們是:

GL_POINTS
GL_LINES
GL_LINE_LOOP
GL_LINE_STRIP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN

我們還沒有討論點或線,所以我只介紹最后的三個 。在我開始之前,我要提醒你,頂點數組可能包含不止一個三角形,以便當您只看到一個物體頂點數組,你要知道,不僅限於這一點。

GL_TRIANGLES - 這個參數意味着OpenGL使用三個頂點來組成圖形。所以,在開始的三個頂點,將用頂點1,頂點2,頂點3來組成一個三角形。完成后,在用下一組的三個頂點來組成三角形,直到數組結束。

GL_TRIANGLE_STRIP - OpenGL的使用將最開始的兩個頂點出發,然后遍歷每個頂點,這些頂點將使用前2個頂點一起組成一個三角形。所以第三個點與第一個,第二個生成一個三角形。第四個點將於第二個,第三個生成三角形。

也就是說,0,1,2這三個點組成一個三角形,1,2,3這三個點也組成一個三角形。

GL_TRIANGLE_FAN - 在跳過開始的2個頂點,然后遍歷每個頂點,讓OpenGL將這些頂點於它們前一個,以及數組的第一個頂點一起組成一個三角形。 第3個點將與 第二個點(前一個)和第一個點(第一個).生成一個三角形。

也就是說,同樣是0,1,2,3這4個頂點。
STRIP狀態下是,0,1,2;1,2,3這2個三角形。
FAN狀態下是,0,1,2;0,2,3這2個三角形。

這次我們將使用 GL_TRIANGLE_FAN ,我們將在顯示區域獲得一個矩形。

 

(注:本教程轉自其他網頁,並加以修改,查看原網頁請點擊這里


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM