Android OpenGl ES2.0編程_相關(guān)概念與繪制頂點(diǎn)

前言
前面介紹了使用 Android 編寫(xiě) OpenGL ES 應(yīng)用的程序框架楞艾,并成功繪制了第一個(gè)OpenGL ES 2.0的小程序草讶,本篇介紹 3D 繪圖的一些基本構(gòu)成要素祭椰,基本概念泥张,重要的函數(shù),最終將實(shí)現(xiàn)一個(gè)頂點(diǎn)的繪制巧骚。
本文是建立在上一篇文章之上赊颠,只修改MyRenderer類格二,其他部分保持不變,如果你沒(méi)有看上一篇文章竣蹦,請(qǐng)先移步Android OpenGl ES2.0編程_第一個(gè)OpenGL小程序

▲ 基本概念

Vertex (頂點(diǎn))
頂點(diǎn)是3D建模時(shí)用到的最小構(gòu)成元素顶猜,頂點(diǎn)定義為兩條或是多條邊交會(huì)的地方。在 3D 模型中一個(gè)頂點(diǎn)可以為多條邊痘括,面或是多邊形所共享长窄。一個(gè)頂點(diǎn)也可以代表一個(gè)點(diǎn)光源或是 Camera 的位置。下圖中標(biāo)識(shí)為黃色的點(diǎn)為一個(gè)頂點(diǎn)(Vertex)纲菌。

三維坐標(biāo)系

三維笛卡兒坐標(biāo)系是在二維笛卡兒坐標(biāo)系的基礎(chǔ)上根據(jù)右手定則增加第三維坐標(biāo)(即Z軸)而形成的挠日。同二維坐標(biāo)系一樣,AutoCAD中的三維坐標(biāo)系有世界坐標(biāo)系WCS(World Coordinate System)和用戶坐標(biāo)系UCS(User Coordinate System)兩種形式翰舌。---百度百科

學(xué)習(xí)OpenGL編程嚣潜,少不了需要了解坐標(biāo)系的概念,這里我們不用理解的那么深椅贱,簡(jiǎn)單的知道和了解最基本的就好懂算,推薦閱讀三維坐標(biāo)系介紹

在3D繪圖中,坐標(biāo)軸遵循右手法則。三維坐標(biāo)系中庇麦,Z軸的正軸方向是根據(jù)右手定則確定的计技。右手定則也決定三維空間中任一坐標(biāo)軸的正旋轉(zhuǎn)方向。
要標(biāo)注X山橄、Y和Z軸的正軸方向垮媒,就將右手背對(duì)著屏幕放置,拇指即指向X軸的正方向航棱。伸出食指和中指睡雇,如右圖所示,食指指向Y軸的正方向,中指所指示的方向即是Z軸的正方向鳍悠。
要確定軸的正旋轉(zhuǎn)方向,如右圖所示,用右手的大拇指指向軸的正方向仿村,彎曲手指。那么手指所指示的方向即是軸的正旋轉(zhuǎn)方向鲤孵。

▲ 點(diǎn)的構(gòu)成
有了之前對(duì)坐標(biāo)系的理解瘩欺,我們知道,在3D繪制中沫屡,一個(gè)點(diǎn)包含x饵隙、y、z坐標(biāo)沮脖。在Android系統(tǒng)中,可以用一個(gè)float數(shù)組金矛、int數(shù)組等來(lái)表示一個(gè)點(diǎn)芯急。如下:

private float[] mArrayVertex = { 0f, 0f, 0f };

為了提高性能,通常將這些數(shù)組存放到 java.io 中定義的 Buffer 類中
新建一個(gè)工具類ToolUtils,把獲取Buffer數(shù)據(jù)的代碼封裝如下

public class ToolUtils {
    /**
     * @param vertexes float 數(shù)組
     * @return 獲取浮點(diǎn)形緩沖數(shù)據(jù)
     */
    public static FloatBuffer getFloatBuffer(float[] vertexes) {
        FloatBuffer buffer;
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertexes.length * 4);
        vbb.order(ByteOrder.nativeOrder());
        buffer = vbb.asFloatBuffer();
        //寫(xiě)入數(shù)組
        buffer.put(vertexes);
        //設(shè)置默認(rèn)的讀取位置
        buffer.position(0);
        return buffer;
    }
}

▲ 繪制一個(gè)點(diǎn)
這里只需修改MyRenderer類的代碼,其余代碼和之前搭建的基礎(chǔ)框架一樣驶俊。MyRenderer.java

public class MyRenderer implements GLSurfaceView.Renderer {
    //頂點(diǎn)數(shù)組
    private float[] mArrayVertex = { 0f, 0f, 0f };

    // 緩沖區(qū)
    private FloatBuffer mBuffer;

    MyRenderer() {
        //獲取浮點(diǎn)形緩沖數(shù)據(jù)
        mBuffer = ToolUtils.getFloatBuffer(mArrayVertex);
    }

    // Surface創(chuàng)建的時(shí)候調(diào)用
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 設(shè)置清屏顏色為黑色(rgba)
        gl.glClearColor(0f, 0f, 0f, 0f);
    }

    // Surface改變的的時(shí)候調(diào)用
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // 設(shè)置OpenGL場(chǎng)景的大小
        gl.glViewport(width / 4, width / 2, width / 2, height / 2);
    }

    // 在Surface上繪制的時(shí)候調(diào)用
    @Override
    public void onDrawFrame(GL10 gl) {

        // 清除屏幕
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        // 允許設(shè)置頂點(diǎn) // GL10.GL_VERTEX_ARRAY頂點(diǎn)數(shù)組
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        // 設(shè)置頂點(diǎn)
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBuffer);

        //設(shè)置點(diǎn)的顏色為紅色
        gl.glColor4f(1f, 0f, 0f, 0f);

        //設(shè)置點(diǎn)的大小
        gl.glPointSize(100f);

        // 繪制點(diǎn)
        gl.glDrawArrays(GL10.GL_POINTS, 0, 1);

        // 禁止頂點(diǎn)設(shè)置
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }
}

▲ 啟用相關(guān)功能及配置說(shuō)明
這里講解部分比較重要的函數(shù)娶耍,之后還有一些常用API在之后的文章會(huì)重點(diǎn)講到

0. glClearColor()
設(shè)置清屏顏色,每次清屏?xí)r饼酿,使用該顏色填充整個(gè)屏幕榕酒。里面參數(shù)分別代表RGBA,取值范圍為[0,1]而不是[0,255]故俐。例如:

gl.glClearColor(0f, 0f, 0f, 0f);

1. glVertexPointer()
設(shè)置一個(gè)指針想鹰,這個(gè)指針指向頂點(diǎn)數(shù)組,后面繪制三角形(或矩形)根據(jù)這里指定的頂點(diǎn)數(shù)組來(lái)讀取數(shù)據(jù)
函數(shù)原型:

void glVertexPointer(int size,int type,int stride,Buffer pointer)

參數(shù)解釋

size —— 每個(gè)頂點(diǎn)的坐標(biāo)維數(shù)药版,必須是2, 3 或者4辑舷,初始值是4。

type —— 指明每個(gè)頂點(diǎn)坐標(biāo)的數(shù)據(jù)類型槽片,允許的符號(hào)常量GL_BYTE, GL_SHORT,GL_FIXED 和GL_FLOAT惩妇,初始值為GL_FLOAT。

stride —— 指明連續(xù)頂點(diǎn)間的位偏移筐乳,如果為0歌殃,頂點(diǎn)被認(rèn)為是緊密壓入矩陣,初始值為0蝙云。

pointer —— 指明頂點(diǎn)坐標(biāo)的緩沖區(qū)氓皱,如果為null,則沒(méi)有設(shè)置緩沖區(qū)勃刨。

2. glClear()
用來(lái)清理緩沖區(qū)波材,并設(shè)置為預(yù)設(shè)值
函數(shù)原型:

glClear(int mask)

mask的值有以下三種

GL_COLOR_BUFFER_BIT —— 表明顏色緩沖區(qū)

GL_DEPTH_BUFFER_BIT —— 表明深度緩沖

GL_STENCIL_BUFFER_BIT —— 表明模型緩沖區(qū)

3. glEnableClientState()
啟用客戶端的某項(xiàng)功能。glEnableClientState和glDisableClientState啟用或禁用客戶端的單個(gè)功能身隐。默認(rèn)的廷区,所有客戶端功能禁用。 array可以是下列符號(hào)常量:

GL_COLOR_ARRAY —— 如果啟用贾铝,顏色矩陣可以用來(lái)寫(xiě)入以及調(diào)用glDrawArrays方法或者glDrawElements方法時(shí)進(jìn)行渲染隙轻。詳見(jiàn)glColorPointer。

GL_NORMAL_ARRAY —— 如果啟用垢揩,法線矩陣可以用來(lái)寫(xiě)入以及調(diào)用glDrawArrays方法或者glDrawElements方法時(shí)進(jìn)行渲染玖绿。詳見(jiàn)glNormalPointer。

GL_TEXTURE_COORD_ARRAY —— 如果啟用叁巨,紋理坐標(biāo)矩陣可以用來(lái)寫(xiě)入以及調(diào)用glDrawArrays方法或者glDrawElements方法時(shí)進(jìn)行渲染斑匪。詳見(jiàn)glTexCoordPointer。

GL_VERTEX_ARRAY —— 如果啟用锋勺,頂點(diǎn)矩陣可以用來(lái)寫(xiě)入以及調(diào)用glDrawArrays方法或者glDrawElements方法時(shí)進(jìn)行渲染蚀瘸。詳見(jiàn)glVertexPointer狡蝶。

GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension)——如果啟用,點(diǎn)大小矩陣控制大小以渲染點(diǎn)和點(diǎn)sprites贮勃。這時(shí)由glPointSize定義的點(diǎn)大小將被忽略牢酵,由點(diǎn)大小矩陣 提供的大小將被用來(lái)渲染點(diǎn)和點(diǎn)sprites。詳見(jiàn)glPointSize衙猪。

4. glDrawArrays()
繪制數(shù)組里面所有點(diǎn)構(gòu)成的各個(gè)三角片
函數(shù)原型:

void glDrawArrays(
    int mode,
    int first,
    int count
);

參數(shù)解釋

mode:有三種取值

  • GL_TRIANGLES:每三個(gè)頂之間繪制三角形馍乙,之間不連接
  • GL_TRIANGLE_FAN:以V0 V1 V2,V0 V2 V3,V0 V3 V4,……的形式繪制三角形
  • GL_TRIANGLE_STRIP:順序在每三個(gè)頂點(diǎn)之間均繪制三角形垫释。這個(gè)方法可以保證從相同的方向上所有三角形均被繪制丝格。以V0 V1 V2 ,V1 V2 V3,V2 V3 V4,……的形式繪制三角形

first:從數(shù)組緩存中的哪一位開(kāi)始繪制,一般都定義為0

count:頂點(diǎn)的數(shù)量

▲ 最終效果圖
看著雖然是一個(gè)正方形棵譬,但實(shí)際它是一個(gè)大小為100f的正方形的點(diǎn)

▲ 完整代碼下載:https://github.com/ChenYXin/OpenGL_ES_2.0_Sample

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末显蝌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子订咸,更是在濱河造成了極大的恐慌曼尊,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脏嚷,死亡現(xiàn)場(chǎng)離奇詭異骆撇,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)父叙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)神郊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人趾唱,你說(shuō)我怎么就攤上這事涌乳。” “怎么了甜癞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵夕晓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我悠咱,道長(zhǎng)蒸辆,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任乔煞,我火速辦了婚禮吁朦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渡贾。我一直安慰自己,他們只是感情好雄右,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布空骚。 她就那樣靜靜地躺著纺讲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪囤屹。 梳的紋絲不亂的頭發(fā)上熬甚,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音肋坚,去河邊找鬼乡括。 笑死,一個(gè)胖子當(dāng)著我的面吹牛智厌,可吹牛的內(nèi)容都是我干的诲泌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼铣鹏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼敷扫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起诚卸,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤葵第,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后合溺,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體卒密,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年棠赛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了栅受。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恭朗,死狀恐怖屏镊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情痰腮,我是刑警寧澤而芥,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站膀值,受9級(jí)特大地震影響棍丐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沧踏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一歌逢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翘狱,春花似錦秘案、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赚导。三九已至,卻和暖如春赤惊,著一層夾襖步出監(jiān)牢的瞬間吼旧,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工未舟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留圈暗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓裕膀,卻偏偏與公主長(zhǎng)得像员串,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子魂角,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容