public class TextureRect { int mProgram;//自定义渲染管线着色器程序id int muMVPMatrixHandle;//总变换矩阵引用id int maPositionHandle; //顶点位置属性引用id int maTexCoorHandle; //顶点纹理坐标属性引用id int uIsButtonDownHandle;//按钮是否按下引用Id int uTypeHandle;//按钮的属性 int uCurrAlphaHandle;//当前按钮的不透明度 int uWidthHandle;//当前按钮的宽度 int uCurrXHandle;//传入的X坐标 int maSTOffset; //水面纹理图的偏移量引用id int uBloodValueHandle;//生命值的引用 FloatBuffer mVertexBuffer;//顶点坐标数据缓冲 FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲 int vCount=0; private boolean isFlow;//当前是否是水面 private boolean flag_flow_go=true;//水面是否运动 private float currStartST=0; //水面纹理坐标的当前起始坐标0~1 //按钮标志位,用来改变按钮的不透明度 private int index=0;//对象id,如果是1,表示当前为按钮,如果为2,表示绘制物体的生命值 public int button_type=0;//按钮的类型 0表示正常显示,1表示按下才透明的按钮,2表示循环变换的按钮,3表示卷动的面板 public float bloodValue;//物体的生命值 public int isButtonDown;//按钮是否按下0表示没有按下,1表示按下 public float currAlpha;//当前的不透明度 public float buttonWidth;//按钮的宽度 public float currX;//传入的X值 public float flowSpeed;//流动的速度 public float[] textures;//定义纹理坐标 //普通构造器 public TextureRect(float width,float height,int mProgram) { //初始化顶数据的initVertexDate方法 initVertexData(width,height,false,1); //初始化着色器的initShader方法 initShader(mProgram); } //按钮/生命值构造器 public TextureRect(float width,float height,int mProgram,int index,int button_type)//1为按钮,2为生命值 { this.index=index; this.button_type=button_type; //初始化顶点坐标与着色数据 initVertexData(width,height,false,1); //初始化shader initShader(mProgram); } //水面构造器 public TextureRect(float width,float height,int mProgram,boolean isWater,int n) { //初始化顶点坐标与着色数据 initVertexData(width,height,false,n); //初始化shader initShader(mProgram); } //纹理流动的构造器 public TextureRect(float width,float height,int mProgram,boolean isFlow,float speed) { this.isFlow=isFlow; this.flowSpeed=speed; //初始化顶点坐标与着色数据 initVertexData(width,height,false,1); //初始化shader initShader(mProgram); //启动一个线程定时换帧 new Thread() { public void run() { while(flag_flow_go) { //所谓水面定时换帧只是修改每帧起始角度即可, //水面顶点Y坐标的变化由顶点着色单元完成 currStartST=(currStartST+0.00008f*flowSpeed)%1; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } //绘制数字的构造器,主要是将纹理坐标传入进来 public TextureRect(float width,float height,float[] textures,int mProgram)//传入宽高和纹理坐标数组 { this.textures=textures; initVertexData(width,height,true,1); initShader(mProgram); } //初始化顶点坐标与着色数据的方法 public void initVertexData(float width,float height,boolean hasTexture,int n) { vCount=4; float vertices[]=new float[] { -width/2,height/2,0, -width/2,-height/2,0, width/2,height/2,0, width/2,-height/2,0 }; //创建顶点坐标数据缓冲 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder());//设置字节顺序为本地操作系统顺序 mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲 mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据 mVertexBuffer.position(0);//设置缓冲区起始位置 if(!hasTexture)//如果没有传入纹理 { textures=new float[]//顶点颜色值数组,每个顶点4个色彩值RGBA { 0,0, 0,n, n,0, n,n }; } //创建顶点纹理坐标数据缓冲 ByteBuffer cbb = ByteBuffer.allocateDirect(textures.length*4); cbb.order(ByteOrder.nativeOrder());//设置字节顺序为本地操作系统顺序 mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲 mTexCoorBuffer.put(textures);//向缓冲区中放入顶点着色数据 mTexCoorBuffer.position(0);//设置缓冲区起始位置 } //初始化着色器的initShader方法 public void initShader(int mProgram) { this.mProgram=mProgram; //获取程序中顶点位置属性引用id maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); //获取程序中顶点纹理坐标属性引用id maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor"); //获取程序中总变换矩阵引用id muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); if(isFlow) { //获取水面纹理图偏移量的引用id maSTOffset=GLES20.glGetUniformLocation(mProgram, "stK"); } if(index==1)//当前为按钮 { uIsButtonDownHandle=GLES20.glGetUniformLocation(mProgram, "isButtonDown");//按钮是否按下 uTypeHandle=GLES20.glGetUniformLocation(mProgram, "type");//按钮的类型 uCurrAlphaHandle=GLES20.glGetUniformLocation(mProgram, "currAlpha");//当前按钮的不透明度 uWidthHandle=GLES20.glGetUniformLocation(mProgram, "width");//当前按钮的宽度 uCurrXHandle=GLES20.glGetUniformLocation(mProgram, "currX");//传入的X坐标 } else if(index==2)//当前为物体的生命值 { uBloodValueHandle=GLES20.glGetUniformLocation(mProgram, "ublood"); } } public void drawSelf(int texId) { //制定使用某套shader程序 GLES20.glUseProgram(mProgram); //将最终变换矩阵传入shader程序 GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0); if(isFlow) { //将水面纹理图的st偏移量传入shader程序 GLES20.glUniform1f(maSTOffset, currStartST); } if(index==1)//如果当前为按钮 { GLES20.glUniform1i(uIsButtonDownHandle, isButtonDown);//按钮是否按下 GLES20.glUniform1i(uTypeHandle, button_type);//按钮的类型 GLES20.glUniform1f(uCurrAlphaHandle, currAlpha);//按钮的不透明度 GLES20.glUniform1f(uWidthHandle, buttonWidth);//按钮的宽度 GLES20.glUniform1f(uCurrXHandle, currX);//传入的X值 } else if(index==2)//如果当前为物体生命值矩形框 { GLES20.glUniform1f(uBloodValueHandle, bloodValue); } //传入顶点位置数据 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_TRIANGLE_STRIP, 0, vCount); } }