opengl es 顏色和着色

上一節介紹了opengl es着色器原理和過程
我們對着色器原理和過程有了較爲詳細的理解,並且重點講解了使用頂點着色器來實現opengl基本圖元(點,直線,三角形)的位置,那麼本節講解opengl es對顏色的繪製。

三角形扇:
之前講解如果想描述一個長方形可以用兩個三角形來描述,比如:
// Triangle 1
-0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f,
// Triangle 2
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
。。。。
很容易發現有很多座標重複的問題,特別是複雜圖形這樣組成座標的數組裏有大量的數據冗餘,爲了解決這個問題提出了三角形扇的概念。如下圖:
這裏寫圖片描述
我們在桌子中間引入一個點(0,0)即1位置作爲起始點,使用相鄰兩個頂點創建第一個三角形,接下來的每個頂點都會創建一個三角形,圍繞起始點按照扇形展開,當最後重複第二個點時我們知道繪製完成。座標位置數組也變成如下:

    /*
        float[] tableVerticesWithTriangles = {
            // Triangle Fan
               0,     0,            
            -0.5f, -0.5f,             
             0.5f, -0.5f,
             0.5f,  0.5f,
            -0.5f,  0.5f,            
            -0.5f, -0.5f,

            // Line 1
            -0.5f, 0f, 
             0.5f, 0f,

            // Mallets
            0f, -0.25f,
            0f,  0.25f 
        };*/

在本例AirHockeyRenderer的onDrawFrame中,代碼如下:

 /**
     * OnDrawFrame is called whenever a new frame needs to be drawn. Normally,
     * this is done at the refresh rate of the screen.
     */
    @Override
    public void onDrawFrame(GL10 glUnused) {
        // Clear the rendering surface.
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw the table.        
        glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

        // Draw the center dividing line.        
        glDrawArrays(GL_LINES, 6, 2);

        // Draw the first mallet.        
        glDrawArrays(GL_POINTS, 8, 1);

        // Draw the second mallet.
        glDrawArrays(GL_POINTS, 9, 1);
    }

glDrawArrays(GL_TRIANGLE_FAN, 0, 6);指定用6個座標值繪製三角形扇。
顏色屬性:
我們要爲每個頂點增加顏色屬性代碼如下:

       //
        // Vertex data is stored in the following manner:
        // 
        // The first two numbers are part of the position: X, Y
        // The next three numbers are part of the color: R, G, B
        //
        float[] tableVerticesWithTriangles = {   
            // Order of coordinates: X, Y, R, G, B

            // Triangle Fan
               0f,    0f,   1f,   1f,   1f,         
            -0.5f, -0.5f, 0.7f, 0.7f, 0.7f,            
             0.5f, -0.5f, 0.7f, 0.7f, 0.7f,
             0.5f,  0.5f, 0.7f, 0.7f, 0.7f,
            -0.5f,  0.5f, 0.7f, 0.7f, 0.7f,
            -0.5f, -0.5f, 0.7f, 0.7f, 0.7f,

            // Line 1
            -0.5f, 0f, 1f, 0f, 0f,
             0.5f, 0f, 1f, 0f, 0f,

            // Mallets
            0f, -0.25f, 0f, 0f, 1f,
            0f,  0.25f, 1f, 0f, 0f
        };

可以看到爲每個頂點增加了三個分量座標分別對應顏色的紅,綠,藍分量,每個分量值在0-1範圍。
打開simple_fragment_shader.glsl和simple_vertex_shader.glsl我們發現裏面沒有了uniform屬性而是varying。varying的意思就是把給他的值進行混合,比如在第一個頂點是紅色,第二個頂點是綠色則使用varying後的效果就是組成第一第二頂點連線的直線離第一個頂點越近越呈現紅色,直線離第二個點越近越呈現綠色,而且這是一種平滑按比例呈現的效果,用公式表達如下:
這裏寫圖片描述
這個公式是應用於每個顏色分量的。如下圖是從紅到綠的直線,
這裏寫圖片描述
則線上各個顏色分量如下圖
這裏寫圖片描述
這裏寫圖片描述

上面是直線按照線性比例來實現這種顏色的平滑變化,如果是三角形則是按照構成三角形面積的分量,原理相似。
值得注意的是在代碼上引入了 private static final int STRIDE =
(POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;因爲我們座標和顏色使用的是同一個緩衝器(這樣有利於節省內存,性能)所以我們需要用STRIDE 來表示內存字節偏移量。所以在
onSurfaceCreated裏面指定位置的時候使用了這個偏移量
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
false, STRIDE, vertexData);指定顏色的時候也使用了這個偏移量STRIDE ,

vertexData.position(POSITION_COMPONENT_COUNT);        
        glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT, 
            false, STRIDE, vertexData);  

本節我們不在使用uniform故在onDrawFrame裏面也不需要glUniform4f方法。同時我們也已經把頂點數據和顏色關聯起來了,故只需要glDrawArrays方法就能搞定。
本文代碼路徑:
https://github.com/pangrui201/OpenGlesProject/tree/master/OpenGlesProject_lesson3

發佈了46 篇原創文章 · 獲贊 22 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章