着色器的編譯和屏幕上面繪圖

   關於opengl es的着色器語言,我推薦一個地址:http://imgtec.eetrend.com/blog/1948,這篇文章寫的至關不錯,你們要是有興趣能夠去看一下。數組

    我在這裏簡單總結一下,uniform在着色器中是隻讀的,不能被修改,它的值只能被opengl es的API注入。Attribute至關於opengl es的API向頂點着色器注入數據的入口,它與uniform的不一樣之處在於:uniform是全局常量,該全局性對頂點着色器與片元着色器都可見;Attributes是針對每個頂點的輸入數據,並且只能在頂點着色器中使用。varying用於從頂點着色器向片斷着色器傳遞數據,在光柵化階段,varying變量會被作線性插值處理。spa

 

     咱們接着講對着色器的編譯。orm

     在Android裏面,着色器文件一遍都放在raw文件夾下面,所以咱們要先把內容讀取到內存中,接下來的步驟以下:對象

      1.建立新的着色器對象。blog

          int shaderID = GLES20.glCreateShader(type);索引

        這裏的type能夠表明頂點着色器的 GLES20.GL_VERTEX_SHADER,和片斷着色器的GLES20.GL_FRAGMENT_SHADER。接口

     2.上傳和編譯着色器的源代碼內存

         GLES20.GLES20.glShaderSource(shaderID, shaderCode);
        GLES20.glCompileShader(shaderID);ci

      這裏的shaderCode表示從raw文件夾下讀取的頂點着色器或片斷着色器的字符串內容。字符串

     3.對頂點着色器和片斷着色器執行第一步和第二步的操做。

     4.新建一個opengl程序,注意,這裏的程序指的是opengl中的組件。

        int programID = GLES20.glCreateProgram();

      5.將咱們以前建立的頂點着色器和片斷着色器的ID附加到這個opengl的程序上。

       GLES20.glAttachShader(programID, vertexShaderID);
       GLES20.glAttachShader(programID, fragmentShaderID);

      6.連接程序,把頂點着色器和片斷着色器連接起來。

       GLES20.glLinkProgram(programID);

       7.使用咱們建立的opengl程序

        GLES20.glUseProgram(programID);

 

        而後咱們講講如何將數據經過opengl es接口注入到着色器當中去。咱們如下邊的着色器爲例:

頂點着色器

attribute vec4 a_Position;

void main()
{
    gl_Position = a_Position;
}

片斷着色器:

precision mediump float;

uniform vec4 u_Color;

void main()
{
    gl_FragColor = u_Color;
}

        給uniform屬性注入數據:

        1. GLES20.得到uniform的位置

         String U_COLOR = "u_Color";

         int  colorPosition = GLES20.glGetUniformLocation(program, U_COLOR);

         2.把數據傳遞給uniform

         GLES20.glUniform4f(colorPosition, 1, 1, 1, 1);

 

         給Attribute屬性注入數據:

         1.得到屬性的位置

         String A_POSITION = "a_Position";

         positionLocation = GLES20.glGetAttribLocation(program, A_POSITION);

         2.關聯屬性與頂點數據的數組

          GLES20.glVertexAttribPointer(positionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, 0, vertexArray);

        3.啓動該頂點數組

        GLES20.glEnableVertexAttribArray(positionLocation);

 

        此外還有關於繪製部分,繪製能夠分爲三種繪製方式:數組繪製,頂點索引繪製,緩衝區繪製

        1.數組繪製,GLES20.glDrawArrays(type, startPosition, count);

        2.頂點 索引繪製,GLES20.glDrawElements(type, indexCount, dataType, indexArray);

        3.緩衝區繪製分爲緩衝區對象的建立和緩衝區的繪製。緩衝區分爲頂點緩衝區和索引緩衝區。

         好比頂點緩衝區對象的建立:

              int buffers[] = new int[1];

              GLES20.glGenBuffers(length,)//生成緩衝區

              bufferID = buffers[0];

              GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);//綁定緩衝區

               FloatBuffer vertexArray = ................//生成floatBuffer,而且注入數據

                vertexArray.position(0);

           GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexArray.capacity()*BYTES_PER_FLOAT, vertexArray, GLES20.GL_STATIC_DRAW); //將native中的數據傳入到GPU

               GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);//解除綁定

 

        建立索引緩衝區對象和建立頂點緩衝區對象其實差很少,只須要對上面的代碼作以下改動:

              1.使用short[]和ShortBuffer做爲類型             

              2.使用GLES20.GL_ELEMENT_ARRAY_BUFFER,而不是GLES20.GL_ARRAY_BUFFER

           經過緩衝區繪製,可使用GLES20.glDrawElements(),只是使用前和使用後須要綁定和解除緩衝區的綁定。

相關文章
相關標籤/搜索