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);
}
}