編輯:關於Android編程
矩陣變換類
package test.com.opengles7_1; import android.opengl.Matrix; /** * Created by hbin on 2016/8/15. */ public class MatrixState { private static float[] mProjMatrix = new float[16];//4x4矩陣 投影用 private static float[] mVMatrix = new float[16];//攝像機位置朝向9參數矩陣 private static float[] mMVPMatrix;//最後起作用的總變換矩陣 static float[] mMMatrix=new float[16] ;//具體物體的移動旋轉矩陣 public static void setInitStack()//獲取不變換初始矩陣 { Matrix.setRotateM(mMMatrix, 0, 0, 1, 0, 0); } public static void translate(float x,float y,float z)//設置沿xyz軸移動 { Matrix.translateM(mMMatrix, 0, x, y, z); } public static void rotate(float angle,float x,float y,float z)//設置繞xyz軸轉動 { Matrix.rotateM(mMMatrix,0,angle,x,y,z); } //設置攝像機 public static void setCamera ( float cx, //攝像機位置x float cy, //攝像機位置y float cz, //攝像機位置z float tx, //攝像機目標點x float ty, //攝像機目標點y float tz, //攝像機目標點z float upx, //攝像機UP向量X分量 float upy, //攝像機UP向量Y分量 float upz //攝像機UP向量Z分量 ) { Matrix.setLookAtM ( mVMatrix, 0, cx, cy, cz, tx, ty, tz, upx, upy, upz ); } //設置透視投影參數 public static void setProjectFrustum ( float left, //near面的left float right, //near面的right float bottom, //near面的bottom float top, //near面的top float near, //near面距離 float far //far面距離 ) { Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far); } //獲取具體物體的總變換矩陣 public static float[] getFinalMatrix() { mMVPMatrix=new float[16]; Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); return mMVPMatrix; } }三角形繪制類
package test.com.opengles7_1; import android.opengl.GLES20; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; /** * Created by hbin on 2016/8/15. * 紋理三角形 */ public class Triangle { int mProgram;//自定義渲染管線程序id int muMVPMatrixHandle;//總變換矩陣引用id int maPositionHandle; //頂點位置屬性引用id int maTexCoorHandle; //頂點紋理坐標屬性引用id String mVertexShader;//頂點著色器 String mFragmentShader;//片元著色器 FloatBuffer mVertexBuffer;//頂點坐標數據緩沖 FloatBuffer mTexCoorBuffer;//頂點紋理坐標數據緩沖 int vCount=0; float xAngle=0;//繞x軸旋轉的角度 float yAngle=0;//繞y軸旋轉的角度 float zAngle=0;//繞z軸旋轉的角度 public Triangle(MySurfaceView mv) { //初始化頂點坐標與著色數據 initVertexData(); //初始化著色器 initShader(mv); } //初始化頂點坐標與著色數據的方法 public void initVertexData() { vCount=3; final float UNIT_SIZE=0.15F; float vertices[]=new float[] { 0*UNIT_SIZE,11*UNIT_SIZE,0, -11*UNIT_SIZE,-11*UNIT_SIZE,0, 11*UNIT_SIZE,-11*UNIT_SIZE,0 }; //創建頂點坐標數據緩沖 ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder());//設置字節順序 mVertexBuffer=vbb.asFloatBuffer(); mVertexBuffer.put(vertices);//向緩沖區放入頂點坐標數據 mVertexBuffer.position(0);//設置緩沖區起始位置 //頂點紋理坐標數據的初始化 float texCoor[]=new float[]//頂點顏色值數組,每個頂點4個色彩值RGBA { 0.5f,0, 0,1, 1,1 }; //創建頂點紋理坐標數據緩沖 ByteBuffer cbb=ByteBuffer.allocateDirect(texCoor.length*4); cbb.order(ByteOrder.nativeOrder()); mTexCoorBuffer=cbb.asFloatBuffer(); mTexCoorBuffer.put(texCoor); mTexCoorBuffer.position(0); } //初始化著色器 public void initShader(MySurfaceView mv) { //加載頂點著色器的腳本內容 mVertexShader=ShaderUtil.loadFromAssetsFile("vertex.sh", mv.getResources()); //加載片元著色器的腳本內容 mFragmentShader=ShaderUtil.loadFromAssetsFile("frag.sh", mv.getResources()); //基於頂點著色器與片元著色器創建程序 mProgram = ShaderUtil.createProgram(mVertexShader, mFragmentShader); //獲取程序中頂點位置屬性引用id maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); //獲取程序中頂點紋理坐標屬性引用id maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor"); //獲取程序中總變換矩陣引用id muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); } public void drawSelf(int texId) { //制定使用某套shader程序 GLES20.glUseProgram(mProgram); MatrixState.setInitStack(); //設置沿Z軸正向位移1 MatrixState.translate(0,0,1); //設置繞y軸旋轉 MatrixState.rotate(yAngle,0,1,0); //設置繞Z軸旋轉 MatrixState.rotate(zAngle,0,0,1); //設置繞x軸旋轉 MatrixState.rotate(xAngle,1,0,0); //將最終變換矩陣傳入shader程序 GLES20.glUniformMatrix4fv(muMVPMatrixHandle,1,false,MatrixState.getFinalMatrix(),0); //為畫筆指定頂點位置數據 GLES20.glVertexAttribPointer( maPositionHandle, 3, GLES20.GL_FLOAT, false, 3*4, mVertexBuffer ); //為畫筆指定頂點紋理坐標數據 GLES20.glVertexAttribPointer( maTexCoorHandle, 2, GLES20.GL_FLOAT, false, 2*4, mTexCoorBuffer ); //允許頂點位置數據數組 GLES20.glEnableVertexAttribArray(maPositionHandle); GLES20.glEnableVertexAttribArray(maTexCoorHandle); //綁定紋理 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId); //繪制紋理矩形 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount); } }
package test.com.opengles7_1; import android.content.Context; import android.content.res.AssetManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.GLUtils; import android.view.MotionEvent; import java.io.IOException; import java.io.InputStream; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; /** * Created by hbin on 2016/8/15. */ public class MySurfaceView extends GLSurfaceView { private final float TOUCH_SCALE_FACTOR=180.0f/320;//角度縮放比例 private SceneRenderer mRenderer;//場景渲染器 private float mPreviousY;//上次的觸控位置Y坐標 private float mPreviousX;//上次的觸控位置X坐標 int textureId;//系統分配的紋理id public MySurfaceView(Context context) { super(context); this.setEGLContextClientVersion(2); mRenderer=new SceneRenderer(); setRenderer(mRenderer); setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); } @Override public boolean onTouchEvent(MotionEvent e){ float y=e.getY(); float x=e.getX(); switch (e.getAction()){ case MotionEvent.ACTION_MOVE: float dy=y-mPreviousY; float dx=x-mPreviousX; mRenderer.texRect.yAngle+=dx*TOUCH_SCALE_FACTOR; mRenderer.texRect.zAngle+=dy*TOUCH_SCALE_FACTOR; } mPreviousY=y; mPreviousX=x; return true; } private class SceneRenderer implements GLSurfaceView.Renderer{ Triangle texRect;//紋理矩形 @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { //設置屏幕背景色 GLES20.glClearColor(0.5f,0.5f,0.5f,1.0f); texRect=new Triangle(MySurfaceView.this); GLES20.glEnable(GLES20.GL_DEPTH_TEST); initTexture(); //關閉背面剪裁 GLES20.glDisable(GLES20.GL_CULL_FACE); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { //設置視窗大小及位置 GLES20.glViewport(0,0,width,height); //計算寬高比 float ratio=(float)width/height; //生成透視投影矩陣 MatrixState.setProjectFrustum(-ratio,ratio,-1,1,1,10); //生成攝像機9參數位置矩陣 MatrixState.setCamera(0,0,3,0f,0f,0f,0f,1.0f,0f); } @Override public void onDrawFrame(GL10 gl) { //清除深度緩沖與顏色緩沖 GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); //繪制紋理矩形 texRect.drawSelf(textureId); } } public void initTexture()//textureId { //生成紋理id int[] textures=new int[1]; GLES20.glGenTextures ( 1,//產生的紋理id數量 textures,//紋理id的數組 0 //偏移量 ); textureId=textures[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,textureId); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); //通過輸入流加載圖片 AssetManager am=getResources().getAssets(); InputStream is=null;; Bitmap bitmap=null; try { // is=am.open("wall.png"); Resources res=this.getContext().getResources(); is=res.openRawResource(R.raw.wall); bitmap= BitmapFactory.decodeStream(is); }catch (Exception ex){ ex.printStackTrace(); } finally { try { is.close(); }catch (Exception ex){ ex.printStackTrace(); } } //實際加載紋理 GLUtils.texImage2D ( GLES20.GL_TEXTURE_2D,//紋理類型,在OpenGL ES中必須為GL10.GL_TEXTURE_2D 0,//紋理的層次,0表示基本圖像層,可以理解為直接貼圖 bitmap,//紋理圖像 0 //紋理邊框尺寸 ); bitmap.recycle(); //紋理加載成功後釋放圖片 } }
package test.com.opengles7_1; import android.content.res.Resources; import android.opengl.GLES20; import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.InputStream; /** * Created by hbin on 2016/8/15. * 加載頂點Shader與片元Shader的工具類 */ public class ShaderUtil { //加載制定shader的方法 public static int loadShader ( int shaderType, //shader的類型 GLES20.GL_VERTEX_SHADER GLES20.GL_FRAGMENT_SHADER String source //shader的腳本字符串 ) { //創建一個新shader int shader = GLES20.glCreateShader(shaderType); //若創建成功則加載shader if (shader != 0) { //加載shader的源代碼 GLES20.glShaderSource(shader, source); //編譯shader GLES20.glCompileShader(shader); //存放編譯成功shader數量的數組 int[] compiled = new int[1]; //獲取Shader的編譯情況 GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); if (compiled[0] == 0) {//若編譯失敗則顯示錯誤日志並刪除此shader Log.e("ES20_ERROR", "Could not compile shader " + shaderType + ":"); Log.e("ES20_ERROR", GLES20.glGetShaderInfoLog(shader)); GLES20.glDeleteShader(shader); shader = 0; } } return shader; } //創建shader程序的方法 public static int createProgram(String vertexSource, String fragmentSource) { //加載頂點著色器 int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); if (vertexShader == 0) { return 0; } //加載片元著色器 int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); if (pixelShader == 0) { return 0; } //創建程序 int program = GLES20.glCreateProgram(); //若程序創建成功則向程序中加入頂點著色器與片元著色器 if (program != 0) { //向程序中加入頂點著色器 GLES20.glAttachShader(program, vertexShader); checkGlError("glAttachShader"); //向程序中加入片元著色器 GLES20.glAttachShader(program, pixelShader); checkGlError("glAttachShader"); //鏈接程序 GLES20.glLinkProgram(program); //存放鏈接成功program數量的數組 int[] linkStatus = new int[1]; //獲取program的鏈接情況 GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); //若鏈接失敗則報錯並刪除程序 if (linkStatus[0] != GLES20.GL_TRUE) { Log.e("ES20_ERROR", "Could not link program: "); Log.e("ES20_ERROR", GLES20.glGetProgramInfoLog(program)); GLES20.glDeleteProgram(program); program = 0; } } return program; } //檢查每一步操作是否有錯誤的方法 public static void checkGlError(String op) { int error; while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { Log.e("ES20_ERROR", op + ": glError " + error); throw new RuntimeException(op + ": glError " + error); } } //從sh腳本中加載shader內容的方法 public static String loadFromAssetsFile(String fname,Resources r) { String result=null; try { InputStream in=r.getAssets().open(fname); int ch=0; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while((ch=in.read())!=-1) { baos.write(ch); } byte[] buff=baos.toByteArray(); baos.close(); in.close(); result=new String(buff,"UTF-8"); result=result.replaceAll("\\r\\n","\n"); } catch(Exception e) { e.printStackTrace(); } return result; } }效果圖
演示效果主要代碼如下自定義的一個EditText,用於實現有文字的時候顯示可以清楚的按鈕:import android.content.Context;import an
完全屬於自己的新聞展示平台,展示給大家,希望大家喜歡。一、新聞的數據庫的構建腳本代碼如下:(使用的mysql5.0 數據庫)SET SQL_MODE = NO_AUTO_
要實現的效果如下考慮到關鍵是動畫效果,所以直接繼承View。不過CheckBox的超類CompoundButton實現了Checkable接口,這一點值得借鑒。下面記錄一
作為一名Android開發者,相信你對Android方法數不能超過65K的限制應該有所耳聞,隨著應用程序功能不斷的豐富,總有一天你會遇到一個異常:Conversion t