附錄(三)繪制三角形

在復(fù)習(xí)一次繪制流程荐糜。

  • 創(chuàng)建頂點和片段著色器
  • 加載編譯
  • 創(chuàng)建程序
  • 附著,連接
  • 使用
  • 得到位置信息 (不太規(guī)范的叫法葛超,就是屬性等參數(shù)的位置)
  • 傳值
  • 繪制

創(chuàng)建著色器

 private final String vertexShaderCode =
      "attribute vec4 vPosition;" +
      "void main() {" +
      "  gl_Position = vPosition;" +
      "}";

private final String fragmentShaderCode =
      "precision mediump float;" +
      "uniform vec4 vColor;" +
      "void main() {" +
      "  gl_FragColor = vColor;" +
      "}";

這個很簡單的暴氏,將傳遞進(jìn)來的頂點屬性直接給內(nèi)置變量。片段著色器直接將傳遞的值給內(nèi)置變量gl_FragColor绣张,這個值會通過后續(xù)步驟之后顯示在屏幕上的答渔。

加載和編譯

  • 創(chuàng)建著色器
//根據(jù)type創(chuàng)建頂點著色器或者片元著色器
int shader = GLES20.glCreateShader(type);
  • 加載程序
//將資源加入到著色器中,并編譯
GLES20.glShaderSource(shader, shaderCode);
  • 編譯程序
GLES20.glCompileShader(shader);
  • 檢查異常
int []arr = new int[1]        GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,arr,0);
       int i = arr[0];
       if (i == 0){
           //失敗了
           int [] length = new int[1];
           GLES20.glGetShaderiv(shader,GLES20.GL_INFO_LOG_LENGTH,length,0);
           if (length[0]>0){
               String s = GLES20.glGetShaderInfoLog(shader);
               System.out.println(s);
           }
       }
       return shader;
   }

創(chuàng)建程序

  • 創(chuàng)建程序
mProgram = GLES20.glCreateProgram();
  • 附著著色器
GLES20.glAttachShader(mProgram,vertexShader);
GLES20.glAttachShader(mProgram,fragmentShader);
  • 連接
GLES20.glLinkProgram(mProgram);
  • 檢查
int lin[] = new int[1];
GLES20.glGetProgramiv(mProgram,GLES20.GL_LINK_STATUS,lin,0);
if (lin[0] == 0){
    String s = GLES20.glGetProgramInfoLog(mProgram);
    System.out.println(s);
}

使用

GLES20.glUseProgram(mProgram);

得到位置

mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

傳值

color使用的是uniform侥涵,可以直接的傳值,傳入數(shù)組就可以了沼撕。

GLES20.glUniform4fv(mColorHandle, 1, color, 0);

但是對于屬性值就比較麻煩一點宋雏,需要使用到FloatBuffer.它 是一個特殊的區(qū)域,就是jvm和操作系統(tǒng)共享的區(qū)域务豺。

float triangleCoords[] = {
            0.5f,  0.5f, 0.0f, // top
            -0.5f, -0.5f, 0.0f, // bottom left
            0.5f, -0.5f, 0.0f  // bottom right
    };


ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(triangleCoords);
vertexBuffer.position(0);

GLES20.glVertexAttribPointer(
        mPositionHandle,
        COORDS_PER_VERTEX,
        GLES20.GL_FLOAT,
        false,
        vertexStride,
        vertexBuffer);

完整代碼

/**
 * 三角形
 */
public class Triangle extends BaseGameScreen {
   
    static final int COORDS_PER_VERTEX = 3;
    private FloatBuffer vertexBuffer;
    static float triangleCoords[] = {
            0.5f,  0.5f, 0.0f, // top
            -0.5f, -0.5f, 0.0f, // bottom left
            0.5f, -0.5f, 0.0f  // bottom right
    };

    //頂點個數(shù)
    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
    //頂點之間的偏移量
    private final int vertexStride = COORDS_PER_VERTEX * 4; // 每個頂點四個字節(jié)
    //設(shè)置顏色磨总,依次為紅綠藍(lán)和透明通道
    float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    private int mPositionHandle;
    private int mColorHandle;
    float d = 0.01F;
    public Triangle(){

    }

    public void create(){
        ByteBuffer bb = ByteBuffer.allocateDirect(
                triangleCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(triangleCoords);
        vertexBuffer.position(0);

        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);
        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram,vertexShader);
        GLES20.glAttachShader(mProgram,fragmentShader);
        GLES20.glLinkProgram(mProgram);
        //程序加入到環(huán)境里面
        GLES20.glUseProgram(mProgram);
//        檢查是否有效
        GLES20.glValidateProgram(mProgram);
        //得到活躍的unifor
        int arr[] = new int[1];
        int arr1[] = new int[1];
        int arr2[] = new int[1];
        int arr3[] = new int[1];
        byte arr4[] = new byte[10];
        GLES20.glGetProgramiv(mProgram,GLES20.GL_ACTIVE_UNIFORMS,arr,0);
        GLES20.glGetActiveUniform(
                mProgram,
                1,
                1,
                arr1,
                1,
                arr2,
                1,
                arr3,
                1,
                arr4,
                0
                );
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
    }

    @Override
    public void surfaceChange(int width, int height) {
        GLES20.glViewport(0,0,width,height);
    }

    @Override
    public void dispose() {

    }


    @Override
    public void render() {
        //獲取位置句柄   屬性句柄

        GLES20.glEnableVertexAttribArray(mPositionHandle);
        //準(zhǔn)備三角形的坐標(biāo)數(shù)據(jù)
        GLES20.glVertexAttribPointer(
                mPositionHandle,
                COORDS_PER_VERTEX,
                GLES20.GL_FLOAT,
                false,
                vertexStride,
                vertexBuffer);
        //獲取片元著色器的vColor成員的句柄

        color[1] = color[1]-d;
        if (color[1]<=0||color[1]>=1){
            d=-d;
        }
        //設(shè)置繪制三角形的顏色
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);
        //繪制三角形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
        //禁止頂點數(shù)組的句柄
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市笼沥,隨后出現(xiàn)的幾起案子蚪燕,更是在濱河造成了極大的恐慌,老刑警劉巖奔浅,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馆纳,死亡現(xiàn)場離奇詭異,居然都是意外死亡汹桦,警方通過查閱死者的電腦和手機(jī)厕诡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來营勤,“玉大人灵嫌,你說我怎么就攤上這事「鹱鳎” “怎么了寿羞?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赂蠢。 經(jīng)常有香客問我绪穆,道長,這世上最難降的妖魔是什么虱岂? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任玖院,我火速辦了婚禮,結(jié)果婚禮上第岖,老公的妹妹穿的比我還像新娘难菌。我一直安慰自己,他們只是感情好蔑滓,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布郊酒。 她就那樣靜靜地躺著,像睡著了一般键袱。 火紅的嫁衣襯著肌膚如雪燎窘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天蹄咖,我揣著相機(jī)與錄音褐健,去河邊找鬼。 笑死澜汤,一個胖子當(dāng)著我的面吹牛蚜迅,可吹牛的內(nèi)容都是我干的舵匾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼慢叨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了务蝠?” 一聲冷哼從身側(cè)響起拍谐,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎馏段,沒想到半個月后轩拨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡院喜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年亡蓉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喷舀。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡砍濒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出硫麻,到底是詐尸還是另有隱情爸邢,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布拿愧,位于F島的核電站杠河,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏浇辜。R本人自食惡果不足惜券敌,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柳洋。 院中可真熱鬧待诅,春花似錦、人聲如沸熊镣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽轧钓。三九已至序厉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毕箍,已是汗流浹背弛房。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留而柑,地道東北人文捶。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓荷逞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親粹排。 傳聞我的和親對象是個殘疾皇子种远,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

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