專案連結
package com.example.opengltest1;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
public class Triangle {
private IntBuffer myVertexBuffer;// 頂點座標資料緩衝
//private FloatBuffer myVertexBuffer;// 頂點座標資料緩衝
//private FloatBuffer myColorBuffer;// 頂點著色資料緩衝
private IntBuffer myColorBuffer;// 頂點著色資料緩衝
private ByteBuffer myIndexBuffer;// 頂點建構的索引資料緩衝
int vCount = 0;// 頂點數量
int iCount = 0;// 索引數量
float yAngle = 0.0f;// 繞Y旋轉的角度
float zAngle = 0.0f;// 繞Z旋轉的角度
public Triangle() {
//初始化三角形的頂點座標暫存
vCount = 3;// 設定頂點數量
int[] vertices = new int[] {// 建立頂點資料陣列
-80000, 60000, 0,
-80000, -60000, 0,
80000, -60000, 0, };
//float[] vertices =new float[] { -80000.0f, 60000.0f, 0.0f, // 0, 左上角
//-80000.0f, -60000.0f, 0.0f, // 1, 左下角
//80000.0f, -60000.0f, 0.0f, // 2, 右下角
//};
/*建立頂點座標資料暫存,由於不同平台位元組順序不同,
* 資料單位不是位元組的要經由ByteBuffer轉換
*/
ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
//配置新的區塊
vbb.order(ByteOrder.nativeOrder());//設定為本機平台的位元組順序
//myVertexBuffer=vbb.asFloatBuffer();
myVertexBuffer=vbb.asIntBuffer();//轉換為Int形式的緩衝,並將頂點作標資料緩衝建立實例
myVertexBuffer.put(vertices);//將頂點座標資料放進緩衝
myVertexBuffer.position(0);//設定緩衝區的起始位置
//初始化三角形的顏色資料暫存
int[] color=new int[]{// 建立頂點顏色陣列,有三個頂點,四個色彩值為RGBA
0,65535,65535,0,
65535,65535,65535,0,
65535,65535,65535,0,
};
//float[] color=new float[]{
//1.0f,1.0f,1.0f,0.0f,
//1.0f,1.0f,1.0f,0.0f,
//1.0f,1.0f,1.0f,0.0f,
//};
/*建立顏色資料暫存,由於不同平台位元組順序不同,
* 資料單位不是位元組的要經由ByteBuffer轉換
*/
ByteBuffer cbb=ByteBuffer.allocateDirect(color.length*4);
//配置新的區塊
cbb.order(ByteOrder.nativeOrder());//設定本機平台的位元組順序
myColorBuffer=cbb.asIntBuffer();//轉換為Int形式的Buffer,並建立顏色資料緩衝的實例
//myColorBuffer=cbb.asFloatBuffer();
myColorBuffer.put(color);//將顏色資料陣列放入緩衝
myColorBuffer.position(0);
//初始化三角型構造索引資料緩衝
iCount=3;
byte[]index=new byte[]{
0,1,2
};
//建立三角形構造資料緩衝,因為此資料陣列本身就是Byte形式,因此不需要作轉換
myIndexBuffer=ByteBuffer.allocateDirect(index.length);
//配置新的區塊
myIndexBuffer.put(index);
myIndexBuffer.position(0);
}
public void drawself(GL10 gl) {
// TODO Auto-generated method stub
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//啟動頂點座標陣列
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//啟動頂點顏色陣列
gl.glRotatef(yAngle, 0, 1, 0);//根據yAngle的角度值,繞Y旋轉
gl.glRotatef(zAngle, 0, 0, 1);//根據zAngle的角度值,繞z旋轉
gl.glVertexPointer(3, GL10.GL_FIXED, 0, myVertexBuffer);
gl.glColorPointer(4, GL10.GL_FIXED, 0, myColorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, iCount, GL10.GL_UNSIGNED_BYTE, myIndexBuffer);
}
}
package com.example.opengltest1; import android.os.Bundle; import android.app.Activity; import android.widget.LinearLayout; public class MainActivity extends Activity { private MySurfaceView mysurfaceview; private LinearLayout lin; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lin=(LinearLayout)findViewById(R.id.LinearLayout1); mysurfaceview=new MySurfaceView(this); mysurfaceview.requestFocus(); mysurfaceview.setFocusableInTouchMode(true); lin.addView(mysurfaceview); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); mysurfaceview.onPause(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); mysurfaceview.onResume(); } }
package com.example.opengltest1; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; public class MyRenderer implements Renderer { Triangle tr = new Triangle(); 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, -4.0f);//把座標系往Z軸負方向平移兩個單位 tr.drawself(gl); } 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);//設定投影模式 } 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);//設置模式 gl.glClearColorx(0, 0, 0, 0);//螢幕背景為黑色(RGBA) gl.glEnable(GL10.GL_DEPTH_TEST);//啟動深度檢測 } }
package com.example.opengltest1; import android.content.Context; import android.opengl.GLSurfaceView; import android.view.MotionEvent; public class MySurfaceView extends GLSurfaceView { private final float TOUCH_SCALE_FATOR=180.0f/320; private MyRenderer myren; private float previousX; private float previousY; public MySurfaceView(Context context) { super(context); // TODO Auto-generated constructor stub myren=new MyRenderer(); this.setRenderer(myren); this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub float x=event.getX(); float y=event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_MOVE: float dy=y-previousY; float dx=x-previousX; myren.tr.yAngle=myren.tr.yAngle+dx*TOUCH_SCALE_FATOR; myren.tr.zAngle=myren.tr.zAngle+dy*TOUCH_SCALE_FATOR; MySurfaceView.this.requestRender(); //break; } previousY=y; previousX=x; return true; } }