使用openGL步驟:
1.創建GLSurfaceView對象
2.創建GLSurfaceView.renderer實現類.
3.設置activity的contentView,以及設置view的render對象.
4.實現render類的過程.
onSurfaceCreate()方法
設置清屏的顏色和啓用頂點緩衝區//設置清屏色
gl.glClearColor(0, 0, 0, 1);
//啓用頂點緩衝區
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);onSurfaceChanged()方法
1.設置viewport(視口//輸出畫面的區域)gl.glViewport(0, 0, width, height);
2.操縱投影矩陣,設置平截頭體(比例通常和視口比例相同,否則輸出畫面會走樣)
//矩陣模式,投影矩陣,openGL基於狀態機 gl.glMatrixMode(GL10.GL_PROJECTION); //加載單位矩陣(歸零) gl.glLoadIdentity(); //平截頭體(視景體) 參數對應,左,右,下,上,近平面,遠平面(畫圖形要在這些值範圍之內,否則要被截裁的) gl.glFrustumf(-ratio, ratio, -1f, 1f, 3, 7);
onDrawFrame()方法
1.清除顏色緩衝區gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
2.操縱模型視圖矩陣,設置眼球的參數
//之前創建的時候是投影矩陣,現在要設置眼球參數的話呀改成模型視圖矩陣,否則可以不改gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity();//加載單位矩陣GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);//gl後第一組三個參數是眼球座標,中間三個參數是眼球的觀察點,後三個參數是眼球向上的向量
3.定義圖形頂點座標值數組(一般用浮點數,整數也可以的)
float[] coords = { 0f,0.5f,0f, -0.5f,-0.5f,0f, 0.5f,-0.5f,0f };
4.將頂點座標轉換成緩衝區數據
//分配字節緩存區空間(效率更高),存放頂點座標數據 ByteBuffer ibb = ByteBuffer.allocateDirect(coords.length * 4);//一個浮點數佔4位 //設置的順序(本地順序) ibb.order(ByteOrder.nativeOrder()); //放置頂點座標數組(第一步是包裝成浮點緩衝區) FloatBuffer fbb = ibb.asFloatBuffer(); fbb.put(coords); //定位指針的位置,從該位置開始讀取頂點數據 ibb.position(0);
5.設置繪圖顏色
gl.glColor4f(1f, 0f, 0f, 1f);//和安卓不同,這裏是rgba 安卓原生的是argb //glColorXX 這裏4是4個浮點數。 f是float
6.指定頂點緩衝區指針
//3:3維點,使用三個座標值表示一個點 //type:每個點的數據類型 //stride:0,跨度. //ibb:指定頂點緩衝區 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, ibb);
7.繪圖(最主要的)
//0:起始點: //3:繪製點的數量 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); //一共三種模式,畫點,畫線,畫三角形(圖元)。平面也是三角形//球和環是無數個三角形
附上 繪製一個三角形的代碼
opengl使用的是笛卡爾座標系,與屏幕座標系不一樣的。左下角纔是原點。
package com.example.administrator.myapplication;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.AttributeSet;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MainActivity extends AppCompatActivity
{
float ratio;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
MyGLSurfaceView view = new MyGLSurfaceView(this);
view.setRenderer(new MyRenderer());//渲染器
setContentView(view);
}
class MyGLSurfaceView extends GLSurfaceView
{
public MyGLSurfaceView(Context context)
{
super(context);
}
public MyGLSurfaceView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
}
class MyRenderer implements android.opengl.GLSurfaceView.Renderer
{
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
//設置表層畫面
gl.glClearColor(0, 0, 0, 1);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//啓用頂點緩存區
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
//設置視口和畫面區域
gl.glViewport(0, 0, width, height);
ratio = (float) width/(float) height;
//矩陣模式,投影矩陣,opengGL基於狀態機
gl.glMatrixMode(GL10.GL_PROJECTION);
//加載單位矩陣
gl.glLoadIdentity();
//平截頭體
gl.glFrustumf(-1f, 1f, -ratio, ratio, 3, 7);
}
@Override
public void onDrawFrame(GL10 gl)
{
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
//模型視圖矩陣
gl.glMatrixMode((GL10.GL_MODELVIEW));
//加載單位矩陣
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0f, 0f, 5f, 0f, 0f, 0f, 0, 1, 0);
//畫三角形
float[] coords = {0f, ratio, 0f, -1f, -ratio, 0f, 1f, -ratio, 0f};
//分配字節緩存空間,存放頂點數據
ByteBuffer ib = ByteBuffer.allocateDirect(coords.length * 4);
//設置的順序(本地順序)
ib.order(ByteOrder.nativeOrder());
//放置頂點數據
FloatBuffer fbb = ib.asFloatBuffer();
fbb.put(coords);
//定位指正的位置。衝該位置讀取頂點數據
ib.position(0);
gl.glColor4f(1f, 0f, 0f, 1f);
//三維的點
//stride//跨度
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, ib);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
}
}
}