OpenGl ES 2.0 Learn For Android(一)世界是三角形的

OpenGl ES 2.0 Learn For Android(一)世界是三角形的

為什么說世界是三角形的呢剑按?常規(guī)我們理解的世界——三維世界,由點(diǎn)線面構(gòu)成。這是一個(gè)比較常規(guī)的認(rèn)知。那么纵朋,理解opengl的世界的時(shí)候,也當(dāng)然由這個(gè)邏輯去想象茄袖。但在實(shí)際繪制的時(shí)候操软,無限這種概念沒法實(shí)際的在計(jì)算機(jī)里進(jìn)行描述。所以opengl的世界宪祥,事實(shí)上由點(diǎn)聂薪、線段、和三角形來組成品山。為什么不是四邊形呢胆建?我想,可能是創(chuàng)始者的強(qiáng)迫癥肘交。希望設(shè)計(jì)是123的邏輯笆载,不是124這種跳過3的邏輯。當(dāng)然涯呻,我只是亂猜凉驻。

前一篇的內(nèi)容在這里。
OpenGl ES 2.0 Learn For Android

1. 三角形的基礎(chǔ)——頂點(diǎn)

即使是世界是三角形構(gòu)成的复罐。但三角形終究也是一個(gè)一個(gè)的點(diǎn)涝登,所以,opengl也是從點(diǎn)開始效诅。

講到點(diǎn)胀滚,自然要講到坐標(biāo)系趟济。opengl使用的是右手三維坐標(biāo)系。


坐標(biāo)系

也就是說咽笼,我們拿著手機(jī)顷编,正對(duì)著它。想象里面的繪制坐標(biāo)的話剑刑,向右是X軸正方向媳纬,向上是Y軸正方向,向你面部的位置是Z軸正方向施掏。而且钮惠,這個(gè)世界只能顯示[-1,1]的內(nèi)容(這里的話不一定對(duì),有可能之后來修正)七芭。那么我們現(xiàn)在先只看一個(gè)面素挽,所以可以暫時(shí)忽略Z軸,理解成原點(diǎn)在手機(jī)屏幕正中央狸驳,向右是X軸正方向毁菱,向上是Y軸正方向。

OpenGL作為本地系統(tǒng)庫(kù)是直接運(yùn)行在硬件上的锌历,在Android里,而我們的代碼是運(yùn)行在Dalvik(現(xiàn)在是ART)上峦筒,導(dǎo)致OpenGL無法去讀取我們的數(shù)據(jù)究西,所以有兩種方案解決上述問題:

  • 從Java調(diào)用本地代碼(JNI)。
    一般我們調(diào)用GLES20包物喷,就是在后臺(tái)使用JNI卤材。

  • 把內(nèi)存從Java堆復(fù)制到本地堆。意思就是改變內(nèi)存分配的方式峦失,Java有個(gè)特殊的類集合扇丛,把Java數(shù)據(jù)復(fù)制到本地內(nèi)存中。

    內(nèi)存從Java堆復(fù)制到本地堆

    FloatBuffer使用方式可以參照下面博客:
    java中的float緩沖區(qū)FloatBuffer

對(duì)應(yīng)代碼使用:

private final FloatBuffer mVertexData;

private float[] mTrianglePoints = {-0.5f, -0.5f, 0.5f, -0.5f, 0f, 0.5f};

mVertexData = ByteBuffer
        .allocateDirect(mTrianglePoints.length * BYTES_PER_FLOAT)
        .order(ByteOrder.nativeOrder())
        .asFloatBuffer();
mVertexData.put(mTrianglePoints);

現(xiàn)在的話尉辑,我們知道有了點(diǎn)帆精,但是怎么告訴opengl呢?

2. OpenGL:頂點(diǎn)著色器和片段著色器###

一般我們定義好物體的頂點(diǎn)隧魄,被讀取到本地內(nèi)存中卓练,在繪制到屏幕的時(shí)候,需要通過管道進(jìn)行傳輸购啄,這類管道其實(shí)也成為著色器襟企。

著色器:會(huì)告訴GPU如何處理繪制數(shù)據(jù)

在OpenGL中,總共有兩種類型的著色器:
(1)頂點(diǎn)著色器(Vertex Shader)生成每個(gè)頂點(diǎn)的最終位置狮含,針對(duì)每個(gè)頂點(diǎn)顽悼,它都會(huì)執(zhí)行一次曼振;一旦最終位置確定了,OpenGL就可以把這些可見頂點(diǎn)的集合組裝成點(diǎn)蔚龙、直線冰评、以及三角形
(2)片段著色器(Fragment Shader)為組成的點(diǎn)、直線府蛇、三角形的每個(gè)片段生成最終的顏色集索,針對(duì)每個(gè)片段,都會(huì)執(zhí)行一次;一個(gè)片段是一個(gè)小的汇跨、單一顏色的長(zhǎng)方形區(qū)域务荆,類似于計(jì)算機(jī)屏幕上的一個(gè)像素。

一旦最后顏色生成后穷遂,OpenGl就會(huì)把它們寫到一塊稱為幀緩沖區(qū)(frame buffer)的內(nèi)存塊中函匕,然后Android會(huì)把這塊幀緩沖區(qū)顯示到屏幕上。

在代碼里蚪黑,我們可以完成一個(gè)最簡(jiǎn)單的頂點(diǎn)著色器:

 private String mVertexShaderCode =
            "attribute vec4 a_Position;     \n" +
            "void main()                    \n" +
            "{                              \n" +
            "    gl_Position = a_Position;  \n" +
            "}   \n";

同樣的盅惜,完成一個(gè)最簡(jiǎn)單的片段著色器:

private String mFragmentShaderCode =
            "precision mediump float; \n" +
            "uniform vec4 u_Color;          \n" +
            "void main()                    \n" +
            "{                              \n" +
            "    gl_FragColor = u_Color;    \n" +
            "}";

關(guān)于attributeuniform,可以參看這篇博客:OpenGL ES 三種類型修飾 uniform attribute varying
顏色是四維向量忌穿,很容易理解(R,G,B,A)抒寂。頂點(diǎn)我們之前說過是三維的,它這里是(X,Y,Z,W)掠剑。W是什么我們之后講屈芜。

3. OpenGL ES的編譯連接過程###

這里要講到,GLES20的接口朴译,都是先生成一個(gè)實(shí)例井佑,拿到一個(gè)句柄,再對(duì)這個(gè)句柄指向的實(shí)例進(jìn)行操作眠寿。熟悉C語(yǔ)言的應(yīng)該會(huì)比較眼熟這個(gè)流程躬翁。java入行的會(huì)感到一點(diǎn)別扭。
1.shader的連接過程:
glCreateShader->glShaderSource->glCompileShader
2.program的生成過程:
glCreateProgram->glAttachShader->glLinkProgram
program是將一個(gè)頂點(diǎn)著色器和一個(gè)片段著色器鏈接在一起生成一個(gè)對(duì)象盯拱。沒有片段著色器盒发,OpenGL就不知道怎么繪制那些組成每個(gè)點(diǎn)、直線和三角形的片段狡逢;沒有頂點(diǎn)著色器迹辐,OpenGL就不知道在哪里繪制這些片段。

//create vertex shader
int vertexShader = compileShader(GL_VERTEX_SHADER, mVertexShaderCode);
//create fragment shader
int fragmentShader = compileShader(GL_FRAGMENT_SHADER, mFragmentShaderCode);
//create program and link two shader
mShaderProgram = linkProgram(vertexShader,fragmentShader);
//use this program
glUseProgram(mShaderProgram);

4. OpenGL ES的賦值繪制過程###

program拿到后甚侣,就是對(duì)變量進(jìn)行賦值繪制了明吩。

        uColorLocation = glGetUniformLocation(mShaderProgram, "u_Color");

        aPositionLocation = glGetAttribLocation(mShaderProgram, "a_Position");

        // Bind our data, specified by the variable vertexData, to the vertex
        // attribute at location A_POSITION_LOCATION.
        mVertexData.position(0);
        glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT,
                false, 0,mVertexData);
        glEnableVertexAttribArray(aPositionLocation);

        glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);

上面拿到了"u_Color""a_Position"對(duì)應(yīng)的變量,并對(duì)"a_Position"也就是頂點(diǎn)變量進(jìn)行了賦值了一個(gè)頂點(diǎn)數(shù)組殷费,對(duì)"u_Color"賦值為白色印荔。

在繪制的時(shí)候

    @Override
    public void onDrawFrame(GL10 glUnused) {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }

這里是從頂點(diǎn)數(shù)組下標(biāo)0開始低葫,繪制3個(gè)頂點(diǎn)。glDrawArrays具體我就不介紹了仍律。這里的參數(shù)有些不同嘿悬,可以參看
https://www.khronos.org/registry/OpenGL-Refpages/es2.0/
下面是效果圖。

drawTriangle

demo地址:
https://github.com/YueZhiFengMing/LearnOpenGl/tree/master/SecondDrawTriangle

參考資料###

  1. java中的float緩沖區(qū)FloatBuffer
  2. OpenGL ES 三種類型修飾 uniform attribute varying
  3. https://www.khronos.org/registry/OpenGL-Refpages/es2.0/
  4. 《OpenGL ES應(yīng)用開發(fā)實(shí)踐指南:Android卷》
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末水泉,一起剝皮案震驚了整個(gè)濱河市善涨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌草则,老刑警劉巖钢拧,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異炕横,居然都是意外死亡源内,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門份殿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膜钓,“玉大人,你說我怎么就攤上這事卿嘲∷绦保” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵拾枣,是天一觀的道長(zhǎng)焚鲜。 經(jīng)常有香客問我,道長(zhǎng)放前,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任糯彬,我火速辦了婚禮凭语,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撩扒。我一直安慰自己似扔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布搓谆。 她就那樣靜靜地躺著炒辉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泉手。 梳的紋絲不亂的頭發(fā)上黔寇,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音斩萌,去河邊找鬼缝裤。 笑死屏轰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的憋飞。 我是一名探鬼主播霎苗,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼榛做!你這毒婦竟也來了唁盏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤检眯,失蹤者是張志新(化名)和其女友劉穎厘擂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轰传,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡驴党,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了获茬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片港庄。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖恕曲,靈堂內(nèi)的尸體忽然破棺而出鹏氧,到底是詐尸還是另有隱情,我是刑警寧澤佩谣,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布把还,位于F島的核電站,受9級(jí)特大地震影響茸俭,放射性物質(zhì)發(fā)生泄漏吊履。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一调鬓、第九天 我趴在偏房一處隱蔽的房頂上張望艇炎。 院中可真熱鬧,春花似錦腾窝、人聲如沸缀踪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)驴娃。三九已至,卻和暖如春循集,著一層夾襖步出監(jiān)牢的瞬間唇敞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厚棵,地道東北人蕉世。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像婆硬,于是被迫代替她去往敵國(guó)和親狠轻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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