OpenGL ES 之二 繪製一個三角形
OpenGL ES 採用的是三維迪卡兒座標系 ,如下圖 ,通常開發3D場景都要對應到這個座標
系中去 , 場景內構建的所用或部分物體的頂點的X Y Z 座標值 已頂點數組的形式給出 ,
如場景有幾個 n 個頂點 , 則座標系有 3n 個 ,則頂點數組的尺寸為 3 n .
OpenGL ES 中有一項重要功能叫做背面剪裁 , 當打開背後剪裁後 , 視角會在一個三角形
的背面時不渲染此三角形 , 可以大大提高渲染效率 .
程式碼 :
public class MySurfaceView extends GLSurfaceView {
.........................
.........................
// 實現Renderer接口,渲染器
private class SceneRenderer implements GLSurfaceView.Renderer
{
Triangle tr=new Triangle();
public SceneRenderer(){
}
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
gl.glEnable(GL10.GL_CULL_FACE); //設置為打開背面剪裁
gl.glShadeModel(GL10.GL_SMOOTH); // 設 置着色模型为平滑着色
gl.glFrontFace(GL10.GL_CCW); // 設 置自定義捲繞顺序為逆時間為正面
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
//清除顏色缓充和深度缓存
gl.glMatrixMode(GL10.GL_MODELVIEW);//設置當前为矩陣模式
gl.glLoadIdentity();// 設置當前矩陣为单位矩陣
gl.glTranslatef(0, 0, -2.0f);//
tr.drawSelf(gl);//
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
float ratio=(float)width/height;
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
gl.glDisable(GL10.GL_DITHER);//關閉抗抖動
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
//設置特定Hint项目的模式,這為設置使用快速模式
gl.glClearColor(0, 0, 0, 0);//设置屏幕背景色为黑色
gl.glEnable(GL10.GL_DEPTH_TEST);//啟用用深度检测
}}}
public class Triangle {
private IntBuffer myVertexBuffer; //頂點坐標數據緩衝
private IntBuffer myColorBuffer; //頂點著色數據緩衝
private ByteBuffer myIndexBuffer; //頂點構建的索引數據
int vCount=0; // 頂點數量
int iCount=0; // 索引數 量
float yAngle=0; //繞y軸旋轉的角度
float zAngle=0; //繞z軸旋轉的角度
public Triangle(){
vCount=3; //一個三角形,3個頂點
final int UNIT_SIZE=10000;//缩放比例
int []vertices=new int[]
{
-8*UNIT_SIZE,6*UNIT_SIZE,0,
-8*UNIT_SIZE,-6*UNIT_SIZE,0,
8*UNIT_SIZE,-6*UNIT_SIZE,0
};
// 創建頂點坐標數據緩存,由於不同平台 Byte 順序不同,數據單元不是 Byte 的(上面的事整型的緩存),一定要經過ByteBuffer轉換,關鍵是通過ByteOrder设置nativeOrder()
ByteBuffer vbb=Byte uffer.allocateDirect(vertices.length*4);
//一個整數四個byte,根據最新分配的內存塊來創建一個有向的緩衝
vbb.order(ByteOrder.nativeOrder()); //設置這個byte緩衝的byte順序為本地平台的byte順序
myVertexBuffer=vbb.asIntBuffer() //轉換為int型緩衝
myVertexBuffer.put(vertices); //向緩衝區中放入頂點坐標數據
myVertexBuffer.position(0); //設置緩衝區的起始位置
final int one=65535; //支持65535色色彩通道
int []colors=new int[] //頂點顏色值數組,每個頂點4個色彩值RGBA
{
one,one,one,0,
one,one,one,0,
one,one,one,0
};
ByteBuffer cbb=ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
myColorBuffer=cbb.asIntBuffer();
myColorBuffer.put(colors);
myColorBuffer.position(0);
//為三角形構造索引數據初始化
iCount=3;
byte []indices=new byte[]
{
0,1,2
};
//創建三角形構造索引數據緩衝
myIndexBuffer=ByteBuffer.allocateDirect(indices.length);
myIndexBuffer.put(indices);
myIndexBuffer.position(0);
}
//GL10是實現接口GL的一公共接口,包含了一系列常量和抽象方法
public void drawSelf(GL10 gl)
{
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //啟用頂點坐標數組
gl.glEnableClientState(GL10.GL_COLOR_ARRAY) ;//啟用頂點顏色數組
gl.glRotatef(yAngle,0,1,0); //根據yAngle的角度值,繞y軸旋轉yAngle
gl.glRotatef(zAngle,0,0,1);
gl.glVertexPointer //為畫筆指定頂點坐標數據
(
3,//每個頂點的坐標數量为3
GL10.GL_FIXED,//點坐標值的類型為GL_FIXED
0,//連續頂點坐標數據之間的間隔
myVertexBuffer //頂點坐標數量
);
gl.glColorPointer //為畫筆指定頂點 顏色數據
(
4,
GL10.GL_FIXED,
0,
myColorBuffer
);
gl.glDrawElements// 繪制圖形
(
GL10.GL_TRIANGLES,//填充模式,這裡是以三角形方式填充
iCount,//頂點數量
GL10.GL_UNSIGNED_BYTE,//索引值的類型
myIndexBuffer //索引值数據
);
}}
留言列表