2012年11月19日 星期一

Android:OpenGL Cube


package com.example.opengltest2;

import ...

public class Cube {
// 頂點座標
float cubeVtx[] = { -1.0f, 1.0f, -1.0f, // v0
-1.0f, 1.0f, 1.0f, // v1
1.0f, 1.0f, 1.0f, // v2
1.0f, 1.0f, -1.0f, // v3
-1.0f, -1.0f, -1.0f, // v4
-1.0f, -1.0f, 1.0f, // v5
1.0f, -1.0f, 1.0f, // v6
1.0f, -1.0f, -1.0f }; // v7

private float colors[] = {
             0.0f,  1.0f,  0.0f,  1.0f,
             0.0f,  1.0f,  0.0f,  1.0f,
             1.0f,  0.5f,  0.0f,  1.0f,
             1.0f,  0.5f,  0.0f,  1.0f,
             1.0f,  0.0f,  0.0f,  1.0f,
             1.0f,  0.0f,  0.0f,  1.0f,
             0.0f,  0.0f,  1.0f,  1.0f,
             1.0f,  0.0f,  1.0f,  1.0f
          };
// 頂點索引
short cubeInx[] = { 0, 1, 2, // Top_Face1
0, 2, 3, // Top_Face2
4, 6, 5, // Bottom_Face1
4, 7, 6, // Bottom_Face2
2, 6, 7, // Left_face1
2, 7, 3, // Left_Face2
0, 4, 1, // Right_Face1
1, 4, 5, // Right_Face2
1, 5, 6, // Front_Face1
1, 6, 2, // Front_Face2
0, 3, 4, // Back_Face1
3, 7, 4 }; // Back_Face2

// 點的緩衝區
private FloatBuffer vertexBuffer;
//顏色的緩衝區
private FloatBuffer colorBuffer;
// 索引值緩衝區
private ShortBuffer indexBuffer;

public cube() {
// 初始化頂點緩衝
ByteBuffer bb = ByteBuffer.allocateDirect(cubeVtx.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(cubeVtx);
vertexBuffer.position(0);

//初始化顏色資料緩衝
ByteBuffer cb = ByteBuffer.allocateDirect(colors.length * 4);
cb.order(ByteOrder.nativeOrder());
colorBuffer = cb.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(0);

// 初始化索引緩衝
ByteBuffer ib = ByteBuffer.allocateDirect(cubeInx.length * 2);
ib.order(ByteOrder.nativeOrder());
indexBuffer = ib.asShortBuffer();
indexBuffer.put(cubeInx);
indexBuffer.position(0);

}

public void draw(GL10 gl) {
// 逆時鐘
 gl.glFrontFace(GL10.GL_CCW);
 // 啟動CULL_FACE
 gl.glEnable(GL10.GL_CULL_FACE);
 // 刪除多邀形的背景
 gl.glCullFace(GL10.GL_BACK);
// 啟動點的緩衝區
 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
 // 為畫筆指定頂點位置和資料格式
//啟動顏色的緩衝區
 gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
 //為畫筆指定頂點顏色資料
 gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
 // 以三點劃出三角形
 gl.glDrawElements(GL10.GL_TRIANGLES, cubeInx.length,
   GL10.GL_UNSIGNED_SHORT, indexBuffer);

}

}



public class OpenGLRenderer implements Renderer {
Cube cube;
public OpenGLRenderer() {
 // 初始化
 cube1=new cube();
}
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
// 清除螢幕和深度緩衝區
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
 // 以單位矩陣取代目前的矩陣
 gl.glLoadIdentity();
 // Z軸轉置 10單位
 gl.glTranslatef(0, 0, -10);
    //可以加上這段讓Cube不斷旋轉
 long time = SystemClock.uptimeMillis()% 4000L;  
   float angle = 0.090f * ((int)time);  
   gl.glRotatef(angle, 1.0f, 0.0f, 0.0f);  
   gl.glRotatef(angle, 0.0f, 1.0f, 0.0f);  
   gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);  
 
    cube1.draw(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();
 // 計算視窗的寬高比率
 GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,
   100.0f);
 //float ratio=(float)width/height;//比例大小
//gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);//設定投影模式
 // 選擇MODELVIEW陣列
 gl.glMatrixMode(GL10.GL_MODELVIEW);
 // 重設MODELVIEW陣列
 gl.glLoadIdentity();
}


註;可以透過openGL Transformation函式或是投影操作, 讓Cube效果更顯著

2012年11月13日 星期二

Android:OpenGL 座標變換

*注意要領*

  1. 注意glPushMatrix以及glPopMatrix的交互使用配合以建構出設想的模式
  2. glTranslatef (float x, float y, float z) 平移座標軸
  3. glRotatef(float angle, float x, float y, float z) 旋轉座標軸
  4. glScalef (float x, float y, float z) 縮大或放小
  5. 可以透過不斷的改變角度或其他參數來達到動態的效果
OpenGLRenderer

package com.example.opengltest2;

import ...

public class OpenGLRenderer implements Renderer {
private Square square;
     private float angle=0;
public OpenGLRenderer() {
 // 初始化
 square = new Square();
}
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
// 清除螢幕和深度緩衝區
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
 // 以單位矩陣取代目前的矩陣
 gl.glLoadIdentity();
 
 gl.glTranslatef(0, 0, -10);//Z軸轉置10單位
 
 //第一個方形,儲存目前陣列
 gl.glPushMatrix();
 //逆時鐘旋轉
 gl.glRotatef(angle, 0, 0, 1);
 //畫出第一個方形
 square.draw(gl);
 //復原回最後的矩陣
 gl.glPopMatrix();
 
 //第二個方形,儲存目前陣列
 gl.glPushMatrix();
 //先旋轉再移動,旋轉時讓第二個方形繞著第一個方形旋轉
 gl.glRotatef(-angle, 0, 0, 1);
 gl.glTranslatef(2, 0, 0);
 //調整大小為第一個方型的一半
 gl.glScalef(.5f, .5f, .5f);
 square.draw(gl);
 
// 第三個方形
 // 存儲目前陣列
 gl.glPushMatrix();
 // 讓第三個方形圍繞著第二個方形旋轉
 gl.glRotatef(-angle, 0, 0, 1);
 // 移動第三個方形
 gl.glTranslatef(2, 0, 0);
 // 調整其大小為第二個方形的一半
 gl.glScalef(.5f, .5f, .5f);
 // 以自己為中心旋轉,12倍目的是為了自轉比較快的效果
 gl.glRotatef(angle * 12, 0, 0, 1);
 // 畫出第三個方形.
 square.draw(gl);

 // 復原成第三個方形前的矩陣
 gl.glPopMatrix();
 // 復原成第二個方形前的矩陣
 gl.glPopMatrix();
 
 angle++;//讓圖形不斷的旋轉

}

@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();
 // 計算視窗的寬高比率
 GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,
   100.0f);
 //float ratio=(float)width/height;//比例大小
//gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);//設定投影模式
 // 選擇MODELVIEW陣列
 gl.glMatrixMode(GL10.GL_MODELVIEW);
 // 重設MODELVIEW陣列
 gl.glLoadIdentity();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
// 設定背景顏色為黑色, 格式是RGBA
 gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
 // 設定流暢的陰影模式
 gl.glShadeModel(GL10.GL_SMOOTH);
 // 深度緩區的設定
 gl.glClearDepthf(1.0f);
 // 啟動深度的測試
 gl.glEnable(GL10.GL_DEPTH_TEST);
 // GL_LEQUAL深度函式測試
 gl.glDepthFunc(GL10.GL_LEQUAL);
 // 設定很好的角度計算模式
 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

}

}






Android:OpenGL 加上顏色


package com.example.opengltest2;

import ...

public class Square {
// 點的陣列
private float vertices[] = { -1.0f, 1.0f, 0.0f, // 0, 左上角
  -1.0f, -1.0f, 0.0f, // 1, 左下角
  1.0f, -1.0f, 0.0f, // 2, 右下角
  1.0f, 1.0f, 0.0f, // 3, 右上角
};

// 顏色的陣列(RGBA)
float[] color=new float[]{
1.0f,0.0f,0.0f,1.0f,//左上角
0.0f,1.0f,0.0f,1.0f,//左下角
0.0f,0.0f,1.0f,1.0f,//右下角
1.0f,1.0f,0.0f,1.0f //右上角
};

// 連接點的次序
private short[] indices = { 0, 1, 2, 0, 2, 3 };

// 點的緩衝區
private FloatBuffer vertexBuffer;

// 顏色的緩衝區
private FloatBuffer colorBuffer;

// 索引值緩衝區
private ShortBuffer indexBuffer;

public Square() {
//初始化頂點座標暫存
// 浮點數是4位元組因此需要把點陣列長度乘以4
 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
 vbb.order(ByteOrder.nativeOrder());//設定為本機平台的位元組順序
 vertexBuffer = vbb.asFloatBuffer();//轉換為float形式的緩衝,並建立實例
 vertexBuffer.put(vertices);//將頂點座標陣列放進緩衝
 vertexBuffer.position(0);////設定緩衝區的起始位置

 //初始化座標顏色暫存,浮點數是4位元組因此需要把點陣列長度乘以4
 ByteBuffer cbb=ByteBuffer.allocateDirect(color.length*4);
 cbb.order(ByteOrder.nativeOrder());
 colorBuffer=cbb.asFloatBuffer();
 colorBuffer.put(color);
 colorBuffer.position(0);

 ////初始化構造索引資料緩衝
 // 短整數是2位元組因此需要把點陣列長度乘以2
 ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
 ibb.order(ByteOrder.nativeOrder());
 indexBuffer = ibb.asShortBuffer();
 indexBuffer.put(indices);
 indexBuffer.position(0);
}

/**
 * 畫圖函式
 *
 * @param gl
 */
public void draw(GL10 gl) {
 // 逆時鐘
 gl.glFrontFace(GL10.GL_CCW);
 // 啟動CULL_FACE
 gl.glEnable(GL10.GL_CULL_FACE);
 // 刪除多邀形的背景
 gl.glCullFace(GL10.GL_BACK);

 // 啟動點的緩衝區
 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
 // 為畫筆指定頂點位置和資料格式
 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

 //啟動顏色的緩衝區
 gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
 //為畫筆指定頂點顏色資料
 gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);

 // 以三點劃出三角形
 gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
   GL10.GL_UNSIGNED_SHORT, indexBuffer);

 // 除能點的緩衝區
 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
 // 除能CULL_FACE
 gl.glDisable(GL10.GL_CULL_FACE);
}

}

Android:OpenGL 建立2D矩形


Square:


package com.example.opengltest2;
import ....

public class Square {
// 點的陣列
private float vertices[] = { -1.0f, 1.0f, 0.0f, // 0, 左上角
  -1.0f, -1.0f, 0.0f, // 1, 左下角
  1.0f, -1.0f, 0.0f, // 2, 右下角
  1.0f, 1.0f, 0.0f, // 3, 右上角
};

// 連接點的次序
private short[] indices = { 0, 1, 2, 0, 2, 3 };

// 點的緩衝區
private FloatBuffer vertexBuffer;

// 索引值緩衝區
private ShortBuffer indexBuffer;

public Square() {
//初始化頂點座標暫存
// 浮點數是4位元組因此需要把點陣列長度乘以4
 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
 vbb.order(ByteOrder.nativeOrder());//設定為本機平台的位元組順序
 vertexBuffer = vbb.asFloatBuffer();//轉換為float形式的緩衝,並建立實例
 vertexBuffer.put(vertices);//將頂點座標陣列放進緩衝
 vertexBuffer.position(0);////設定緩衝區的起始位置

 ////初始化構造索引資料緩衝
 // 短整數是2位元組因此需要把點陣列長度乘以2
 ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
 ibb.order(ByteOrder.nativeOrder());
 indexBuffer = ibb.asShortBuffer();
 indexBuffer.put(indices);
 indexBuffer.position(0);
}

/**
 * 畫圖函式
 *
 * @param gl
 */
public void draw(GL10 gl) {
 // 逆時鐘
 gl.glFrontFace(GL10.GL_CCW);
 // 啟動CULL_FACE
 gl.glEnable(GL10.GL_CULL_FACE);
 // 刪除多邀形的背景
 gl.glCullFace(GL10.GL_BACK);

 // 啟動點的緩衝區
 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
 // 指定位置和資料格式
 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

 // 以三點劃出三角形
 gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
   GL10.GL_UNSIGNED_SHORT, indexBuffer);

 // 除能點的緩衝區
 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
 // 除能CULL_FACE
 gl.glDisable(GL10.GL_CULL_FACE);
}

}

OpenGLRenderer

package com.example.opengltest2;
import ...

public class OpenGLRenderer implements Renderer {
private Square square;

public OpenGLRenderer() {
 // 初始化
 square = new Square();
}
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
// 清除螢幕和深度緩衝區
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
 // 以單位矩陣取代目前的矩陣
 gl.glLoadIdentity();
 // Z軸轉置 4 單位
 gl.glTranslatef(0, 0, -4);
 // 畫出方形
 square.draw(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();
 // 也可以使用GLU內建的投影方法設置
 //GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f);
 float ratio=(float)width/height;//計算寬高比例大小
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);//設定投影模式
 // 選擇MODELVIEW陣列
 gl.glMatrixMode(GL10.GL_MODELVIEW);
 // 重設MODELVIEW陣列
 gl.glLoadIdentity();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
// 設定背景顏色為黑色, 格式是RGBA
 gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
 // 設定流暢的陰影模式
 gl.glShadeModel(GL10.GL_SMOOTH);
 // 深度緩區的設定
 gl.glClearDepthf(1.0f);
 // 啟動深度的測試
 gl.glEnable(GL10.GL_DEPTH_TEST);
 // GL_LEQUAL深度函式測試
 gl.glDepthFunc(GL10.GL_LEQUAL);
 // 設定很好的角度計算模式
 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

}

}

2012年11月12日 星期一

Android:OpenGL視界設定

1.MainActiviry


package com.example.opengltest2;

import ....

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //GLSurfaceView也可以使用圖形化工具建立,再使用findViewById叫進來
       GLSurfaceView view=new GLSurfaceView(this);
       view.setRenderer(new OpenGLRenderer());
       this.setContentView(view);
    } 
}


2.OpenGLRenderer


package com.example.opengltest2;

import ...

public class OpenGLRenderer implements Renderer {

@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
// 清除螢幕和深度緩衝區
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
 // 以單位矩陣取代目前的矩陣
 gl.glLoadIdentity();
}

@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();
 // 這邊也可使用GLU內建的投影方法
 //GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,100.0f);
 float ratio=(float)width/height;//計算視窗的寬高比例大小
  gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);//設定投影模式
 // 選擇MODELVIEW陣列
 gl.glMatrixMode(GL10.GL_MODELVIEW);
 // 重設MODELVIEW陣列
 gl.glLoadIdentity();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
// 設定背景顏色為黑色, 格式是RGBA (這邊基本上是固定組態設定)
 gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
 // 設定流暢的陰影模式
 gl.glShadeModel(GL10.GL_SMOOTH);
 // 深度緩區的設定
 gl.glClearDepthf(1.0f);
 // 啟動深度的測試
 gl.glEnable(GL10.GL_DEPTH_TEST);
 // GL_LEQUAL深度函式測試
 gl.glDepthFunc(GL10.GL_LEQUAL);
 // 設定很好的角度計算模式
 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

}

}

2012年10月30日 星期二

Android:OpenGL 建立


專案連結
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);
 }
}

MainActivity.java
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();
    }


}

MyRenderer.java
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);//啟動深度檢測
    }

}

MySurfaceView.java
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;
    }



}

2012年9月6日 星期四

Android:QR-Code掃描以及SimpleAdapter應用

1.新建立一個XML layout,用來顯示ListView呈現的介面,這邊就簡單3個TextView


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

</LinearLayout>

2. Java Code


package com.example.qrcodetest;

import....
public class MainActivity extends Activity {
ListView listview;
//建構SimpleAdapter所需之參數,用來放置要顯示在ListView的資訊
ArrayList<HashMap<String,String>> list=new ArrayList<HashMap<String,String>>();
private int requestCode = 1;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listView1);

}

public void but_onclic(View v) {
//啟動QR-Code Scanner,此為固定步驟
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, requestCode);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
//取回掃描到的資料
String content = data.getStringExtra("SCAN_RESULT");
//切割字串資料
String[] result = content.split("\n");
//宣告HashMap<String,String>,並將切割好的資料一一放入
HashMap<String,String>latte=new HashMap<String,String>();
if(result.length>0){
latte.put("name", result[0]);
latte.put("tel", result[1]);
latte.put("addr", result[2]);
}
//再將HashMap放回ArrayList,準備建構SimpleAdapter
list.add(latte);
importData2List();
}
}else{
Toast.makeText(this, "scan error", Toast.LENGTH_SHORT).show();
}

}

private void importData2List() {
// TODO Auto-generated method stub
SimpleAdapter simpleadapter = new SimpleAdapter(
this,        //設定接口環境
list,   //設定接口集合容器(ArrayList)
R.layout.raw,//資料顯示用的UI XML檔 
new String[] { "name", "tel", "addr" },//資料欄位相對於Key
new int[] { R.id.textView1, R.id.textView2, R.id.textView3 }//資料顯示UI元件的id
);
listview.setAdapter(simpleadapter);
}

}