OpenGL構建簡單物體

1.幾何圖形類
1.1點
1.2平面圓
1.3圓柱體
2.物體構建器
2.1用三角扇(GL_TRIANGLE_FAN)構造圓
2.2用三角形(GL_TRIANGLE_STRIP)構造圓柱體側面
3.將要生成的物體封裝成各自類
3.1Puck
3.2Mallet
3.3Table
4.簡單的矩陣層次結構
4.1投影矩陣:即三維空間在屏幕上的顯示方式(一般onSurfaceChanged中作設置)
4.2視圖矩陣:即攝像頭相關設置(一般onSurfaceChanged中作設置)
4.3模型矩陣:即旋轉、縮放、移動操作(一般onDrawFrame中作設置)
4.4三者矩陣組合(相乘)後傳遞給着色器矩陣,以這種方式把事物分開,使操作場景和物體變得更加容易。
5.setLookAtM(rm, rmOffset, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
rm:存儲視圖矩陣的目標矩陣
rmOffset:從rm的偏移量rmOffset開始存儲矩陣數據
eyeX, eyeY, eyeZ:攝像頭(眼睛)位置
centerX, centerY, centerZ:攝像頭面向的中心位置,即屏幕中心顯示位置
upX, upY, upZ:攝像頭(眼睛)正上方
6.渲染器代碼

package com.example.firstopengl;

import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glViewport;
import static android.opengl.Matrix.multiplyMM;
import static android.opengl.Matrix.perspectiveM;
import static android.opengl.Matrix.rotateM;
import static android.opengl.Matrix.setIdentityM;
import static android.opengl.Matrix.setLookAtM;
import static android.opengl.Matrix.translateM;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.example.firstopengl.objs.Mallet;
import com.example.firstopengl.objs.Puck;
import com.example.firstopengl.objs.Table;
import com.example.firstopengl.programs.ColorShaderProgram;
import com.example.firstopengl.programs.TextureShaderProgram;
import com.example.firstopengl.util.TextureHelper;

import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;

public class MyRenderer implements Renderer {
    private final Context context;

    //投影矩陣,即三維空間在屏幕上的顯示方式
    private final float[] projectionMatrix = new float[16]; 
    //模型矩陣,即旋轉、縮放、移動操作
    private final float[] modelMatrix = new float[16];  
    //視圖矩陣,即攝像頭相關設置
    private final float[] viewMatrix = new float[16];
    //視圖投影矩陣,即 視圖矩陣*投影矩陣
    private final float[] viewProjectionMatrix = new float[16];
    //模型視圖投影矩陣,該矩陣最後傳遞給着色器,即 模型矩陣*視圖矩陣*投影矩陣 
    private final float[] modelViewProjectionMatrix = new float[16];

    //着色器程序
    private TextureShaderProgram textureProgram;
    private ColorShaderProgram colorProgram;
    //紋理
    private int texture;

    //objs
    private Table table;
    private Puck puck;
    private Mallet mallet;

    public MyRenderer(Context context) {
        // TODO Auto-generated constructor stub
        this.context = context;
    }

    // 繪製每一幀時,GLSurfaceView調用(suface創建後)
    @Override
    public void onDrawFrame(GL10 gl) {
        // TODO Auto-generated method stub
        // 清除屏幕顏色
        glClear(GL_COLOR_BUFFER_BIT);

        //繪製table
        positionTableInScene();
        textureProgram.useProgram();
        textureProgram.setUniforms(modelViewProjectionMatrix, texture);
        table.bindData(textureProgram);
        table.draw();

        //繪製mallet
        positionObjInScene(0f, mallet.height/2f, -0.4f);
        colorProgram.useProgram();
        colorProgram.setUniforms(modelViewProjectionMatrix, 1f, 0f, 0f);
        mallet.bindData(colorProgram);
        mallet.draw();

        positionObjInScene(0f, mallet.height/2f, 0.4f);
        colorProgram.setUniforms(modelViewProjectionMatrix, 0f, 0f, 1f);
        mallet.draw();

        //繪製puck
        positionObjInScene(0f, mallet.height/2f, 0f);
        colorProgram.setUniforms(modelViewProjectionMatrix, 0.8f, 0.8f, 1f);
        puck.bindData(colorProgram);
        puck.draw();
    }

    // suface視圖大小改變時,GLSurfaceView調用(suface創建後)
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // TODO Auto-generated method stub
        // 設置視圖大小
        glViewport(0, 0, width, height);
        //創建透視投影矩陣
        perspectiveM(projectionMatrix, 0, 
                45,                         //攝像頭焦距,即觀察視野大小
                (float)width/(float)height, //屏幕的寬高比
                1f, 10f);                   //攝像頭到近遠平面的距離
        //創建視圖矩陣,即攝像頭相關設置
        setLookAtM(viewMatrix, 0, 
                0f, 1.2f, 2.2f, //攝像頭位置
                0f, 0f, 0f,     //觀察點
                0f, 1f, 0f);    //攝像頭正上方
        //視圖投影矩陣  = 投影矩陣 * 視圖矩陣
        multiplyMM(viewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0);
    }

    // suface創建時,GLSurfaceView調用
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // TODO Auto-generated method stub
        // 清空屏幕的顏色
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

        mallet = new Mallet(0.08f, 0.15f, 32);
        puck = new Puck(0.06f, 0.02f, 32);
        table = new Table();

        textureProgram = new TextureShaderProgram(context);
        colorProgram = new ColorShaderProgram(context);

        texture = TextureHelper.loadTexture(context, R.drawable.ic_launcher);
    }

    /**
     * table座標作模型矩陣變換,即繞x軸旋轉-90度       
     * 模型視圖投影矩陣 = 模型矩陣*視圖矩陣*投影矩陣
     */
    private void positionTableInScene(){
        setIdentityM(modelMatrix, 0);
        rotateM(modelMatrix, 0, -90f, 1f, 0f, 0f);
        multiplyMM(modelViewProjectionMatrix, 0, viewProjectionMatrix, 0,
                modelMatrix, 0);
    }

    /**
     * 物體座標作模型矩陣變換,即在前者modelMatrix矩陣上再作移動操作來確定下面物體繪製的位置
     * 模型視圖投影矩陣 = 模型矩陣*視圖矩陣*投影矩陣
     * @param x
     * @param y
     * @param z
     */
    private void positionObjInScene(float x, float y, float z){
        setIdentityM(modelMatrix, 0);
        translateM(modelMatrix, 0, x, y, z);
        multiplyMM(modelViewProjectionMatrix, 0, viewProjectionMatrix, 0,
                modelMatrix, 0);
    }
}

7.源碼:https://github.com/HQlin/ShaderOpenGL/commits/master

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