根據書上教程運行代碼報錯,2.2的黑屏無效果,4.1的閃退。後研究發現,問題出在在一個物體同時啟用瞭顏色數組和紋理,註釋掉
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
運行即可。
核心代碼如下
package com.xieyuan.test; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.Random; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Intent; import android.opengl.GLSurfaceView.Renderer; import android.opengl.GLUtils; import android.view.KeyEvent; import android.view.MotionEvent; public class GLRender implements Renderer{ private final static int ONE=0x10000; //星星總數 private final static int NUM=50; //存放星星的數組 private Star[] stars=new Star[NUM]; //閃爍的星星 boolean twinkle=true; //離觀察者的距離 float ZOOM=-10f; //星星的傾角 float tilt=90f; //閃爍星星的自轉 float spin; private boolean key; Random random=new Random(); //紋理ID private int texture; IntBuffer coord=GLNioUtil.IntBufferUtil(new int[]{ 0,0,ONE,0,ONE,ONE,0,ONE }); IntBuffer vertexs=GLNioUtil.IntBufferUtil(new int[]{ -ONE-ONE,0, ONE,-ONE,0, ONE,ONE,0, -ONE,ONE,0 }); ByteBuffer indices=GLNioUtil.ByteBufferUtil(new byte[]{ 1,0,2,3 }); @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { //啟用陰影平滑 gl.glShadeModel(GL10.GL_SMOOTH); //清除屏幕為黑色背景 gl.glClearColor(0f, 0f, 0f, 0f); //透視修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); //創建紋理 IntBuffer intBuffer=IntBuffer.allocate(1); gl.glGenTextures(1, intBuffer); texture=intBuffer.get(); gl.glBindTexture(GL10.GL_TEXTURE_2D, texture); gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap[3], 0); //啟用紋理映射 gl.glEnable(GL10.GL_TEXTURE_2D); gl.glShadeModel(GL10.GL_SMOOTH); gl.glClearColor(0f, 0f, 0f, 0.5f); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); //設置混色函數 gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE); //啟用混色 gl.glEnable(GL10.GL_BLEND); for(int i=0;i<NUM;i++){ Star star=new Star(); star.angle=0f; //所有星星的角度都是從0開始 star.dist=(float)i/(float)NUM*5.0f; //計算星星裡中間的距離 star.r=random.nextInt(256); // 為star[loop]設置隨機紅色分量 star.g=random.nextInt(256); // 為star[loop]設置隨機紅色分量 star.b=random.nextInt(256); // 為star[loop]設置隨機紅色分量 stars[i] = star; } } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { float ratio=(float)width/(float)height; //設置場景大小 gl.glViewport(0, 0, width, height); //設置投影舉證 gl.glMatrixMode(GL10.GL_PROJECTION); //重置投影矩陣 gl.glLoadIdentity(); //設置視口大小 gl.glFrustumf(-ratio, ratio, -1,1, 1, 10); //設置模型觀察矩陣 gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); } @Override public void onDrawFrame(GL10 gl) { //清除屏幕和深度緩存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT); //選擇紋理 gl.glBindTexture(GL10.GL_TEXTURE_2D, texture); for(int i=0;i<NUM;i++){ gl.glLoadIdentity(); // 深入屏幕裡面 gl.glTranslatef(0f, 0f, ZOOM); // 傾斜視角 gl.glRotatef(tilt, 1f, 0f, 0f); // 旋轉至當前所畫星星的角度 gl.glRotatef(stars[i].angle,0f,1f,0f); // 沿X軸正向移動 gl.glTranslatef(stars[i].dist, 0f, 0f); // 取消當前星星的角度 gl.glRotatef(-stars[i].angle, 0f, 1f, 0f); // 取消屏幕傾斜 gl.glRotatef(-tilt, 1f, 0f, 0f); //設置頂點數組 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //設置顏色數組 //gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // 啟用閃爍效果 if(twinkle){ // 使用byte型數值指定一個顏色 gl.glColor4f((float)stars[NUM-i-1].r/255f, (float)stars[NUM-i-1].g/255f, (float)stars[NUM-i-1].b/255f, 1f ); gl.glVertexPointer(3, GL10.GL_FIXED, 0,vertexs); gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, coord); coord.position(0); vertexs.position(0); indices.position(0); //gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_BYTE,indices); gl.glFinish(); } //繞z軸旋轉星星 gl.glRotatef(spin, 0f,0f,1f); // 使用byte型數值指定一個顏色 gl.glColor4f((float)stars[(NUM-i)-1].r/255.0f,(float)stars[(NUM-i)-1].g/255.0f,(float)stars[(NUM-i)-1].b/255.0f,1.0f); gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertexs); gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, coord); coord.position(0); vertexs.position(0); indices.position(0); //繪制正方形結束 gl.glFinish(); // gl.glDisableClientState(GL10.GL_COLOR_ARRAY); //取消頂點數組 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); spin+=0.01f; // 星星的公轉 stars[i].angle+=(float)(i)/(float)NUM; // 改變星星的自轉角度 stars[i].dist-=0.01f; // 改變星星離中心的距離 if (stars[i].dist<0.0f) // 星星到達中心瞭麼 { stars[i].dist+=5.0f; // 往外移5個單位 stars[i].r=random.nextInt(256); // 賦一個新紅色分量 stars[i].g=random.nextInt(256); // 賦一個新綠色分量 stars[i].b=random.nextInt(256); // 賦一個新藍色分量 } } } } class Star{ int r,g,b; float dist; //星星距離中心的距離 float angle=0f; //當前星星所處的角度 }
效果: