天天看點

Android 音視訊開發(六) : OpenGL ES API,學習紋理繪制,能夠使用 OpenGL 顯示一張圖檔紋理原理顯示圖檔代碼示例:

紋理

紋理是物體表面的一幅或幾幅二維圖形,也是紋理貼圖。

原理

紋理映射的坐标系,紋理映射坐标系和頂點着色器的坐标系不一樣

頂點坐标系:

Android 音視訊開發(六) : OpenGL ES API,學習紋理繪制,能夠使用 OpenGL 顯示一張圖檔紋理原理顯示圖檔代碼示例:

紋理坐标系:紋理坐标用浮點數來表示,範圍一般從0.0到1.0,左上角坐标為(0.0,0.0),右上角坐标為(1.0,0.0),左下角坐标為(0.0,1.0),右下角坐标為(1.0,1.0),具體如下:

Android 音視訊開發(六) : OpenGL ES API,學習紋理繪制,能夠使用 OpenGL 顯示一張圖檔紋理原理顯示圖檔代碼示例:

顯示圖檔

主要是修改頂點着色器和片元着色器。比正方形多了一個vec2的參數。

Android 音視訊開發(六) : OpenGL ES API,學習紋理繪制,能夠使用 OpenGL 顯示一張圖檔紋理原理顯示圖檔代碼示例:

                                                                圖檔着色器

Android 音視訊開發(六) : OpenGL ES API,學習紋理繪制,能夠使用 OpenGL 顯示一張圖檔紋理原理顯示圖檔代碼示例:

                                                                   正方形着色器

代碼示例:

public class SquareRenderer extends BackgroundRender implements GLSurfaceView.Renderer {
    private FloatBuffer vertexBuffer;
    private ShortBuffer indexBuffer;
    private final String vertexShaderCode =
            "attribute vec4 vPosition;" +
                    "uniform mat4 vMatrix;" +
                    "void main() {" +
                    "  gl_Position = vMatrix*vPosition;" +
                    "}";

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

    private int mProgram;

    static final int COORDS_PER_VERTEX = 3;
    static float triangleCoords[] = {
            -0.5f, 0.5f, 0.0f, // top left
            -0.5f, -0.5f, 0.0f, // bottom left
            0.5f, -0.5f, 0.0f, // bottom right
            0.5f, 0.5f, 0.0f  // top right
    };

    static short index[] = {
            0, 1, 2, 0, 2, 3
    };

    private int mPositionHandle;
    private int mColorHandle;

    private float[] mViewMatrix = new float[16];
    private float[] mProjectMatrix = new float[16];
    private float[] mMVPMatrix = new float[16];

    //頂點個數
    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
    //頂點之間的偏移量
    private final int vertexStride = COORDS_PER_VERTEX * 4; // 每個頂點四個位元組

    private int mMatrixHandler;

    //設定顔色,依次為紅綠藍和透明通道
    float color[] = {0.0f, 1.0f, 0.0f, 1.0f ,
            1.0f, 0.0f, 0.0f, 1.0f,
            0.0f, 0.0f, 1.0f, 1.0f};


    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        ByteBuffer bb = ByteBuffer.allocateDirect(
                triangleCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(triangleCoords);
        vertexBuffer.position(0);

        ByteBuffer cc = ByteBuffer.allocateDirect(index.length * 2);
        cc.order(ByteOrder.nativeOrder());
        indexBuffer = cc.asShortBuffer();
        indexBuffer.put(index);
        indexBuffer.position(0);

        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,
                vertexShaderCode);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
                fragmentShaderCode);

        //建立一個空的OpenGLES程式
        mProgram = GLES20.glCreateProgram();
        //将頂點着色器加入到程式
        GLES20.glAttachShader(mProgram, vertexShader);
        //将片元着色器加入到程式中
        GLES20.glAttachShader(mProgram, fragmentShader);
        //連接配接到着色器程式
        GLES20.glLinkProgram(mProgram);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        //計算寬高比
        float ratio = (float) width / height;
        //設定透視投影
        Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
        //設定相機位置
        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 7.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
        //計算變換矩陣
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectMatrix, 0, mViewMatrix, 0);
    }

    @Override
    public void onDrawFrame(GL10 gl10) {
        //将程式加入到OpenGLES2.0環境
        GLES20.glUseProgram(mProgram);
        //擷取變換矩陣vMatrix成員句柄
        mMatrixHandler = GLES20.glGetUniformLocation(mProgram, "vMatrix");
        //指定vMatrix的值
        GLES20.glUniformMatrix4fv(mMatrixHandler, 1, false, mMVPMatrix, 0);
        //擷取頂點着色器的vPosition成員句柄
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        //啟用正方形頂點的句柄
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        //準備正方形的坐标資料
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                vertexStride, vertexBuffer);
        //擷取片元着色器的vColor成員的句柄
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        //設定繪制正方形的顔色
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);

        //索引法繪制正方形
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, index.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
        //禁止頂點數組的句柄
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }

}
           

項目位址:https://github.com/ChloeDimen/AudioAndVideo

繼續閱讀