一,OpenGL和OpenGL ES
簡介
OpenGL體系簡單,具有跨平臺的特性,不像Direct 3D只能在Windows系統上運行,因此OpenGL具有很廣泛的適應性——不僅只用於大型圖形工作站,也適用於PC。
OpenGL是高效,簡潔的開放圖形庫接口,定義了一個跨編程語言,跨平臺的編程接口規範,主要用於三維圖形編程。
在手機端上運行OpenGL有些不太合適,所以Android系統內置的是OpenGL ES。
OpenGL ES是免費的,跨平臺的,功能完善的2D/3D圖形庫接口API,它針對多種嵌入式程序專門設計,它是一個精心提取出來的OpenGL的子集。
OpenGL ES刪除了Open GL中glBegin/glEnd,四邊形,多邊形等非絕對必要的特性。
Android專門爲OpenGL支持增加了android.opengl包,在該包下提供了GLSurfaceView,GLU,GL Utils等工具類,通過這些工具類在Android應用中使用OpenGL ES更加方。
GLSurfaceView
在Android平臺上實現OpenGL的view用GLSurfaceView和GLSurfaceView.Renderer。
GLSurfaceView是用來連接OpenGL ES和android的view。
GLSurfaceView位於android.opengl包類,繼承自SurfaceView。
GLSurfaceView.Renderer
渲染器,是一個接口,位於GLSurfaceView類中。
MyRenderer
onSurfaceCreated——在Surface創建的時候調用
onSurfaceChanged——在Surface改變的時候調用
onDrawFrame——在Surface上繪製的時候調用
基礎框架
public class MainActivity extends AppCompatActivity {
GLSurfaceView glSurfaceView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glSurfaceView = new GLSurfaceView(this);
SecondActivity secondActivity = new SecondActivity(); //渲染器
glSurfaceView.setRenderer(secondActivity); //渲染器關聯起來
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);//RENDERMODE_CONTINUOUSLY:持續渲染,機器會爆
setContentView(glSurfaceView);
}
}
================
public class SecondActivity implements GLSurfaceView.Renderer {
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0,255,0,0); //背景色
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
}
}
二,繪製點
1,定義頂點數組
2,獲取浮點形緩衝數據
3,設置清屏顏色,onSurfaceCreated裏調用glClearColor設置清屏顏色。
4,設置允許設置頂點,glEnableClientState(int array)調用客戶端的功能。
public class MainActivity extends FragmentActivity {
GLSurfaceView glSurfaceView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glSurfaceView = new GLSurfaceView(this);
SecondActivity secondActivity = new SecondActivity(); //渲染器
glSurfaceView.setRenderer(secondActivity); //渲染器關聯起來
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);//RENDERMODE_CONTINUOUSLY:持續渲染,機器會爆
setContentView(glSurfaceView);
}
}
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class SecondActivity implements GLSurfaceView.Renderer {
private float[] mArray = new float[]{0f,0.5f,0f};
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0,255,0,0); //背景色
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0,0,width,height);//起始座標
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清屏
//GL_COLOR_BUFFER_BIT:表明顏色緩衝區
//GL_DEPTH_BUFFER_BIT:表明深度緩衝區
//GL_STENCIL_BUFFER_BIT:表明模型緩衝區
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
//GL_VERTEX_ARRAY:如果啓用,頂點矩陣可以用來寫入
//GL_COLOR_ARRAY:如果啓用,顏色矩陣可以用來寫入
//GL_NORMAL_ARRAY:如果啓用,法線矩陣可以用來寫入(用於光照處理)
//GL_TEXTURE_COORD_ARRAY:如果啓用,紋理座標矩陣可以用來寫入
gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray));//指定數組頂點用
//size:設置每個頂點的座標維數
//type:GL_BYTE,GL_SHORT,GL_FIXED,GL_FLOAT,初始值爲GL_FLOAT
//stride:指明連續頂點的位偏移,如果爲0,頂點被認爲是緊密壓入矩陣,初始值爲0
//pointer:指明頂點座標的緩衝區,如果爲null,則沒有設置緩衝區
gl.glColor4f(0,0,1,0);//畫圖顏色
gl.glPointSize(80f);//大小
gl.glDrawArrays(GL10.GL_POINTS,0,1);//畫點
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
}
}
public class ThirdActivity {
public static FloatBuffer getFloatBuffer(float[] vertexs){
FloatBuffer buffer;
ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length*4);
qbb.order(ByteOrder.nativeOrder());
buffer = qbb.asFloatBuffer();
buffer.put(vertexs);
buffer.position(0);
return buffer;
}
}
三,圖形繪製(三角形,矩形,正方形)
public class SecondActivity implements GLSurfaceView.Renderer {
private float[] mArray = new float[]{
/* -0.6f,0.6f,
0f,-0.2f,
0f,0f,*/
0.2f,0.6f,
0f,0.6f,
0f,0f};
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0,0,0,0); //背景色
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0,0,width,height);//起始座標
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清理緩衝區,並設置爲預設值
//GL_COLOR_BUFFER_BIT:表明顏色緩衝區
//GL_DEPTH_BUFFER_BIT:表明深度緩衝區
//GL_STENCIL_BUFFER_BIT:表明模型緩衝區
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
//GL_VERTEX_ARRAY:頂點矩陣可以
gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray));//指定數組頂點用
gl.glColor4f(255,255,255,0);//畫圖顏色
gl.glDrawArrays(GL10.GL_TRIANGLES,0,5);//畫點
//GL_POINTS:繪製獨立的點
//GL_LINE_STRIP:繪製連續的線段,不封閉
//GL_LINE_LOOP:繪製連續的線段,封閉
//GL_LINES:頂點兩兩連接,爲多條線段構成
//GL_TRIANGLES:每隔三個頂點構成一個三角形
//GL_TRIANGLE_STRIP:每相鄰三個頂點組成一個三角形
//GL_TRIANGLE_FAN:以一個點爲三角形公共頂點,組成一系列相鄰的三角形
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
}
}
四,圖形變換(移動、旋轉、縮放、着色)
視角變換:人動,物體不動。 模型變換:物體動,人不動。
投影變換:人遠近調整。 視窗變換:把像素按照比例轉化後顯示到屏幕上。
視角變換和模型變換(平移,旋轉,縮放)
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0,0,width,height);//起始座標
//gl.glTranslatef(0.6f,0.3f,0f); //平移
//gl.glRotatef(45,0f,1f,0f);//旋轉
//gl.glScalef(0.5f,0.5f,0.5f);//縮放
}
着色
int[] colors = new int[]{
65535,0,0,0, //紅
0,65535,0,0, //綠
0,0,65535,0, //藍
};
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清理緩衝區,並設置爲預設值
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray));//指定數 組頂點用,轉二進制
gl.glColorPointer(4,GL10.GL_FIXED,0,ThirdActivity.getIntBuffer(colors));//多色
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
}
public static IntBuffer getIntBuffer(int [] vertexs){
IntBuffer buffer;
ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length*4);
qbb.order(ByteOrder.nativeOrder());
buffer = qbb.asIntBuffer();
buffer.put(vertexs);
buffer.position(0);
return buffer;
}
五,3D圖形繪製(三棱錐,立方體)
public class SecondActivity implements GLSurfaceView.Renderer {
private float[] mArray = new float[]{
0.0f,0.5f,0.0f,
-0.5f,-0.5f,-0.2f,
0.5f,0.5f,-0.2f,
0.0f,-0.6f,0.2f,
};
int[] colors = new int[]{
65535,0,0,0, //紅
0,65535,0,0, //綠
0,0,65535,0, //藍
0,65535,65535,0, //藍
};
byte [] taperFacets= new byte[]{
0,1,2,
0,1,3,
1,2,3,
0,2,3,
};
public float b=45;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0,0,0,0); //背景色
gl.glShadeModel(GL10.GL_SMOOTH); //打開平滑着色模式
//gl.glTranslatef(0.6f,0f,0f); //平移
gl.glEnable(GL10.GL_DEPTH_TEST); //啓用Z軸,啓動3D
gl.glDepthFunc(GL10.GL_LEQUAL); //被遮擋的顏色要被顯示出來
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0,0,width,height);//起始座標
gl.glMatrixMode(GL10.GL_PROJECTION); //正交投影
gl.glLoadIdentity();//初始化單位矩陣
//設置寬高比
float a = (float)width/height;
gl.glFrustumf(-a,a,-1,1,1f,1000f); //設置透視投影的大小
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清理緩衝區,並設置爲預設值
gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);//清除深度緩衝區
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//啓用顏色矩陣
gl.glMatrixMode(GL10.GL_MODELVIEW); //物體變化前提
gl.glLoadIdentity();
gl.glTranslatef(0f,0f,-2.0f); //平移,遠離我們
gl.glRotatef(b,-0.1f,-0.1f,0.0f);
gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray)); //設置
gl.glColorPointer(4,GL10.GL_FIXED,0,ThirdActivity.getIntBuffer(colors));
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP,ThirdActivity.getByteBuffer(taperFacets).remaining(),
GL10.GL_UNSIGNED_BYTE,ThirdActivity.getByteBuffer(taperFacets)); //畫圖模式、數組名、
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
b+=1;
}
}
public class SecondActivity implements GLSurfaceView.Renderer {
private float[] mArray = new float[]{
0.5f,0.5f,0.5f,
0.5f,-0.5f,0.5f,
-0.5f,-0.5f,0.5f,
-0.5f,0.5f,0.5f,
0.5f,0.5f,-0.5f,
0.5f,-0.5f,-0.5f,
-0.5f,-0.5f,-0.5f,
-0.5f,0.5f,-0.5f,
};
int[] colors = new int[]{
65535,0,0,0, //紅
0,0,65535,0, //紅
0,65535,0,0, //紅
65535,65535,0,0, //紅
0,65535,65535,0, //紅
65535,0,65535,0, //紅
0,0,0,0, //紅
65535,65535,65535,0, //紅
};
byte [] taperFacets= new byte[]{
0,1,2,
0,2,3,
2,3,7,
2,6,7,
0,3,7,
0,4,7,
4,5,6,
4,6,7,
0,1,4,
1,4,5,
1,2,6,
1,5,6
};
public float b=45;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0,0,0,0); //背景色
//gl.glShadeModel(GL10.GL_SMOOTH); //打開平滑着色模式
//gl.glTranslatef(0.6f,0f,0f); //平移
gl.glEnable(GL10.GL_DEPTH_TEST); //啓用Z軸,啓動3D
gl.glDepthFunc(GL10.GL_LEQUAL); //被遮擋的顏色要被顯示出來
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0,0,width,height);//起始座標
gl.glMatrixMode(GL10.GL_PROJECTION); //正交投影
gl.glLoadIdentity();//初始化單位矩陣
//設置寬高比
float a = (float)width/height;
gl.glFrustumf(-a,a,-1,1,1f,1000f); //設置透視投影的大小
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//清理緩衝區,並設置爲預設值
gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);//清除深度緩衝區
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//允許頂點數組
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//啓用顏色矩陣
gl.glMatrixMode(GL10.GL_MODELVIEW); //物體變化前提
gl.glLoadIdentity();
gl.glTranslatef(0f,0f,-2.0f); //平移,遠離我們
gl.glRotatef(b,-0.1f,-0.1f,0.0f);
gl.glVertexPointer(3,GL10.GL_FLOAT,0,ThirdActivity.getFloatBuffer(mArray)); //設置
gl.glColorPointer(4,GL10.GL_FIXED,0,ThirdActivity.getIntBuffer(colors));
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP,ThirdActivity.getByteBuffer(taperFacets).remaining(),
GL10.GL_UNSIGNED_BYTE,ThirdActivity.getByteBuffer(taperFacets)); //畫圖模式、數組名、
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//停止
b+=1;
}
}
六,3D圖形-貼圖
public class MainActivity extends Activity {
// 定義旋轉角度
private float anglex = 0f;
private float angley = 0f;
static final float ROTATE_FACTOR = 60;
// 定義手勢檢測器實例
GestureDetector detector;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// 創建一個GLSurfaceView,用於顯示OpenGL繪製的圖形
GLSurfaceView glView = new GLSurfaceView(this);
// 創建GLSurfaceView的內容繪製器
MyRenderer myRender = new MyRenderer(this);
// 爲GLSurfaceView設置繪製器
glView.setRenderer(myRender);
setContentView(glView);
// 創建手勢檢測器
}
public class MyRenderer implements Renderer
{
// 立方體的頂點座標(一共是36個頂點,組成12個三角形)
private float[] cubeVertices = { -0.6f, -0.6f, -0.6f, -0.6f, 0.6f,
-0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, -0.6f, -0.6f,
-0.6f, -0.6f, -0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
0.6f, 0.6f, 0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f,
0.6f, -0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, 0.6f,
0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f, 0.6f,
-0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f,
0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f,
-0.6f, 0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, 0.6f,
0.6f, 0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f,
-0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
-0.6f, 0.6f, -0.6f, };
// 定義立方體所需要的6個面(一共是12個三角形所需的頂點)
private byte[] cubeFacets = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, };
// 定義紋理貼圖的座標數據
private float[] cubeTextures = { 1.0000f, 1.0000f, 1.0000f, 0.0000f,
0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 1.0000f,
1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f,
1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f,
0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f,
1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f,
0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f,
0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f };
private Context context;
private FloatBuffer cubeVerticesBuffer;
private ByteBuffer cubeFacetsBuffer;
private FloatBuffer cubeTexturesBuffer;
// 定義本程序所使用的紋理
private int texture;
public MyRenderer(Context main)
{
this.context = main;
// 將立方體的頂點位置數據數組包裝成FloatBuffer;
cubeVerticesBuffer = floatBufferUtil(cubeVertices);
// 將立方體的6個面(12個三角形)的數組包裝成ByteBuffer
cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets);
// 將立方體的紋理貼圖的座標數據包裝成FloatBuffer
cubeTexturesBuffer = floatBufferUtil(cubeTextures);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// 關閉抗抖動
gl.glDisable(GL10.GL_DITHER);
// 設置系統對透視進行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glClearColor(0, 0, 0, 0);
// 設置陰影平滑模式
gl.glShadeModel(GL10.GL_SMOOTH);
// 啓用深度測試
gl.glEnable(GL10.GL_DEPTH_TEST);
// 設置深度測試的類型
gl.glDepthFunc(GL10.GL_LEQUAL);
// 啓用2D紋理貼圖
gl.glEnable(GL10.GL_TEXTURE_2D);
// 裝載紋理
loadTexture(gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
// 設置3D視窗的大小及位置
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 onDrawFrame(GL10 gl)
{
// 清除屏幕緩存和深度緩存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 啓用頂點座標數據
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// 啓用貼圖座標數組數據
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // ①
// 設置當前矩陣模式爲模型視圖。
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
// 把繪圖中心移入屏幕2個單位
gl.glTranslatef(0f, 0.0f, -2.0f);
// 旋轉圖形
gl.glRotatef(angley, 0, 1, 0);
gl.glRotatef(anglex, 1, 0, 0);
// 設置頂點的位置數據
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVerticesBuffer);
// 設置貼圖的座標數據
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer); // ②
// 執行紋理貼圖
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture); // ③
// 按cubeFacetsBuffer指定的面繪製三角形
gl.glDrawElements(GL10.GL_TRIANGLES, cubeFacetsBuffer.remaining(),
GL10.GL_UNSIGNED_BYTE, cubeFacetsBuffer);
// 繪製結束
gl.glFinish();
// 禁用頂點、紋理座標數組
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// 遞增角度值以便每次以不同角度繪製
angley++;
}
private void loadTexture(GL10 gl)
{
Bitmap bitmap = null;
try
{
// 加載位圖
bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.huaji);
int[] textures = new int[1];
// 指定生成N個紋理(第一個參數指定生成一個紋理)
// textures數組將負責存儲所有紋理的代號
gl.glGenTextures(1, textures, 0);
// 獲取textures紋理數組中的第一個紋理
texture = textures[0];
// 通知OpenGL將texture紋理綁定到GL10.GL_TEXTURE_2D目標中
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
// 設置紋理被縮小(距離視點很遠時被縮小)時的濾波方式
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
// 設置紋理被放大(距離視點很近時被方法)時的濾波方式
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// 設置在橫向、縱向上都是平鋪紋理
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
GL10.GL_REPEAT);
// 加載位圖生成紋理
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
}
finally
{
// 生成紋理之後,回收位圖
if (bitmap != null)
bitmap.recycle();
}
}
}
// 定義一個工具方法,將float[]數組轉換爲OpenGL ES所需的FloatBuffer
private FloatBuffer floatBufferUtil(float[] arr)
{
FloatBuffer mBuffer;
// 初始化ByteBuffer,長度爲arr數組的長度*4,因爲一個int佔4個字節
ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
// 數組排列用nativeOrder
qbb.order(ByteOrder.nativeOrder());
mBuffer = qbb.asFloatBuffer();
mBuffer.put(arr);
mBuffer.position(0);
return mBuffer;
}
}