openGl 編寫流程

1,創建頂點數組

2,自己寫 頂點着色器 和片元着色器

3,將java聲明的頂點數組 顏色數組 通過類似於jni接口 傳遞給 gl語言的變量

public class FGLView extends GLSurfaceView {
    public FGLView(Context context) {
        super(context);
    }

    // 三角形  等腰三角形 正方形 立方體
    public FGLView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // opengl版本
        setEGLContextClientVersion(2);
        setRenderer(new FGLRender(this));
        // 設置渲染模式 按需渲染 效率高 自己調用渲染 requestRender();
//        requestRender();

        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }
}
public class FGLRender implements GLSurfaceView.Renderer {

    private View mView;
    Triangle triangle;

    public FGLRender(View mView) {
        this.mView = mView;
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0,0,0,0);
        triangle = new Triangle();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        triangle.onSurfaceChanged(gl,width,height);
    }

    // 不斷被調用 inviladate 被requestRender()手動調用
    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT );
        triangle.onDrawFrame(gl);
    }
}
public class Triangle {

    // openGl 操作

    // 初始化 地址
    int mProgram;

    // 渲染
    // 像素點
    static float triangleCoords[] = {
            0.5f, 0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
    };

    // 把像素頂點數據傳輸到GPU的管道
    private FloatBuffer vertexBuffer;

    // native 函數 寫好了
    // -----------------------------------------------------------------------
    // 頂點着色器在GPU中執行的代碼,可以表示位gl代碼
    private String vertextShaderCode = "attribute vec4 vPosition;" +
            "uniform mat4 vMatrix;" +
            "void main(){" +
            "gl_Position = vMatrix*vPosition;" +
            "}";
    // 片元着色器代碼
    private String fragmentShaderCode = "precision mediump float;" +
            "uniform vec4 vColor;" +
            "void main(){" +
            "gl_FragColor = vColor;" +
            "}";
    // ------------------------------------------------------------------------

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

    public void onSurfaceChanged(GL10 gl,int width,int height){

        // 固定的寫法

        // 計算寬高比
        float ratio = (float) width/height;

        // 投影矩陣
        Matrix.frustumM(mProjectMatrix,0,-ratio,ratio,-1,1,3,120);

        // 設置相機
        Matrix.setLookAtM(mViewMatrix,0,0,0,7,  // 攝像機的座標
                0f, 0f,0f, // 目標物的座標
                0f,1f,0f); // 相機方向

        // 計算變化矩陣
        Matrix.multiplyMM(mMVPMatrix,0,mProjectMatrix,0,mViewMatrix,0);

    }

    public Triangle() {
        // float 類型是四個字節
        ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
        // GPU的排列順序,默認的順序
        bb.order(ByteOrder.nativeOrder());
        // 定義一個float管道,把bytebuffer通過這個管道傳到gpu
        vertexBuffer = bb.asFloatBuffer();
        // 把這門語言 推送 給GPU
        vertexBuffer.put(triangleCoords);
        vertexBuffer.position(0);


        // GL 2.0版本創建
        // ,創建頂點着色器,並在GPU中進行編譯
        int shader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        GLES20.glShaderSource(shader, vertextShaderCode);
        GLES20.glCompileShader(shader);

        // 創建片元着色器,並在GPU中進行編譯
        int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
        GLES20.glCompileShader(fragmentShader);

        // 將片元着色器和頂點着色器 噹噹統一程序進行管理
        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, shader);
        GLES20.glAttachShader(mProgram, fragmentShader);

        // 連接到着色器程序
        GLES20.glLinkProgram(mProgram);
    }

    float color[] = {1.0f,1.0f,1.0f,1.0f};

    public void onDrawFrame(GL10 gl) {

        // 渲染
        GLES20.glUseProgram(mProgram);

        // 矩陣
        int mMatrixHandler = GLES20.glGetUniformLocation(mProgram,"vMatrix");
        GLES20.glUniformMatrix4fv(mMatrixHandler,1,false,mMVPMatrix,0);

        // 指針 native 的指針, 指向GPU的某個內存區域, vPosition
        int mPositionHandler = GLES20.glGetAttribLocation(mProgram, "vPosition");
        // 打開, 允許對gl的變量進行讀寫
        GLES20.glEnableVertexAttribArray(mPositionHandler);
        GLES20.glVertexAttribPointer(mPositionHandler, 3, GLES20.GL_FLOAT, false,
                3 * 4, vertexBuffer);
        int mColorHandler = GLES20.glGetUniformLocation(mProgram,"vColor");
        GLES20.glUniform4fv(mColorHandler,1,color,0);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3);
        // 關閉
        GLES20.glDisableVertexAttribArray(mPositionHandler);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章