六角星的创建

其基本效果图如下所示:



Sixpointed stars类:


import static com.bn.Sample5_1.ShaderUtil.createProgram;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;

import android.opengl.GLES20;
import android.opengl.Matrix;

//六角星
public class SixPointedStar 
{	
	int mProgram;//自定义渲染管线着色器程序id
    int muMVPMatrixHandle;//总变换矩阵引用
    int maPositionHandle; //顶点位置属性引用  
    int maColorHandle; //顶点颜色属性引用  
    String mVertexShader;	//顶点着色器代码脚本 
    String mFragmentShader;	//片元着色器代码脚本
    static float[] mMMatrix = new float[16];	//具体物体的3D变换矩阵,包括旋转、平移、缩放
	
	FloatBuffer   mVertexBuffer;//顶点坐标数据缓冲
	FloatBuffer   mColorBuffer;//顶点着色数据缓冲
    int vCount=0;    
    float yAngle=0;//绕y轴旋转的角度
    float xAngle=0;//绕z轴旋转的角度
    final float UNIT_SIZE=1;
    
    public SixPointedStar(MySurfaceView mv,float r,float R,float z)
    {    	
    	//调用初始化顶点数据的initVertexData方法
    	initVertexData(R,r,z);
    	//调用初始化着色器的intShader方法     
    	initShader(mv);
    }
    
    //自定义初始化顶点数据的initVertexData方法
    public void initVertexData(float R,float r,float z)
    {
		List<Float> flist=new ArrayList<Float>();
		float tempAngle=360/6;
		for(float angle=0;angle<360;angle+=tempAngle)
		{
			//第一个三角形
			//第一个中心点
			flist.add(0f);
			flist.add(0f);
			flist.add(z);
			//第二个点
			flist.add((float) (R*UNIT_SIZE*Math.cos(Math.toRadians(angle))));
			flist.add((float) (R*UNIT_SIZE*Math.sin(Math.toRadians(angle))));
			flist.add(z);
			//第三个点
			flist.add((float) (r*UNIT_SIZE*Math.cos(Math.toRadians(angle+tempAngle/2))));
			flist.add((float) (r*UNIT_SIZE*Math.sin(Math.toRadians(angle+tempAngle/2))));
			flist.add(z);
			
			//第二个三角形
			//第一个中心点
			flist.add(0f);
			flist.add(0f);
			flist.add(z);
			//第二个点
			flist.add((float) (r*UNIT_SIZE*Math.cos(Math.toRadians(angle+tempAngle/2))));
			flist.add((float) (r*UNIT_SIZE*Math.sin(Math.toRadians(angle+tempAngle/2))));
			flist.add(z);
			//第三个点
			flist.add((float) (R*UNIT_SIZE*Math.cos(Math.toRadians(angle+tempAngle))));
			flist.add((float) (R*UNIT_SIZE*Math.sin(Math.toRadians(angle+tempAngle))));
			flist.add(z);
		}
		vCount=flist.size()/3;
		float[] vertexArray=new float[flist.size()];
		for(int i=0;i<vCount;i++)
		{
			vertexArray[i*3]=flist.get(i*3);
			vertexArray[i*3+1]=flist.get(i*3+1);
			vertexArray[i*3+2]=flist.get(i*3+2);
		}
		ByteBuffer vbb=ByteBuffer.allocateDirect(vertexArray.length*4);
		vbb.order(ByteOrder.nativeOrder());	//设置字节顺序为本地操作系统顺序
		mVertexBuffer=vbb.asFloatBuffer();
		mVertexBuffer.put(vertexArray);
		mVertexBuffer.position(0);
		
		
		
        
        //顶点着色数据的初始化================begin============================
		float[] colorArray=new float[vCount*4];
		for(int i=0;i<vCount;i++)
		{
			if(i%3==0){//中心点为白色
				colorArray[i*4]=1;
				colorArray[i*4+1]=1;
				colorArray[i*4+2]=1;
				colorArray[i*4+3]=0;
			}
			else{//边上的点为淡蓝色
				colorArray[i*4]=0.45f;
				colorArray[i*4+1]=0.75f;
				colorArray[i*4+2]=0.75f;
				colorArray[i*4+3]=0;
			}
		}
		ByteBuffer cbb=ByteBuffer.allocateDirect(colorArray.length*4);
		cbb.order(ByteOrder.nativeOrder());	//设置字节顺序为本地操作系统顺序
		mColorBuffer=cbb.asFloatBuffer();
		mColorBuffer.put(colorArray);
		mColorBuffer.position(0);
        //特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
        //转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
        //顶点着色数据的初始化================end============================

    }

    //自定义初始化着色器的intShader方法
    public void initShader(MySurfaceView mv)
    {
    	//加载顶点着色器的脚本内容
        mVertexShader=ShaderUtil.loadFromAssetsFile("vertex.sh", mv.getResources());
        //加载片元着色器的脚本内容
        mFragmentShader=ShaderUtil.loadFromAssetsFile("frag.sh", mv.getResources());  
        //基于顶点着色器与片元着色器创建程序
        mProgram = createProgram(mVertexShader, mFragmentShader);
        //获取程序中顶点位置属性引用id  
        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
        //获取程序中顶点颜色属性引用id  
        maColorHandle= GLES20.glGetAttribLocation(mProgram, "aColor");
        //获取程序中总变换矩阵引用id
        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");  
    }
    
    public void drawSelf()
    {        
    	 //制定使用某套shader程序
    	 GLES20.glUseProgram(mProgram);        
    	 //初始化变换矩阵
         Matrix.setRotateM(mMMatrix,0,0,0,1,0);
         //设置沿Z轴正向位移1
         Matrix.translateM(mMMatrix,0,0,0,1);
         //设置绕y轴旋转
         Matrix.rotateM(mMMatrix,0,yAngle,0,1,0);
         //设置绕z轴旋转
         Matrix.rotateM(mMMatrix,0,xAngle,1,0,0);  
         //将最终变换矩阵传入shader程序
         GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(mMMatrix), 0); 
         //为画笔指定顶点位置数据
         GLES20.glVertexAttribPointer  
         (
         		maPositionHandle,   
         		3, 
         		GLES20.GL_FLOAT, 
         		false,
                3*4, 
                mVertexBuffer
         );       
         //为画笔指定顶点着色数据
         GLES20.glVertexAttribPointer  
         (
        		maColorHandle, 
         		4, 
         		GLES20.GL_FLOAT, 
         		false,
                4*4,   
                mColorBuffer
         );   
         //允许顶点位置数据数组
         GLES20.glEnableVertexAttribArray(maPositionHandle);  
         GLES20.glEnableVertexAttribArray(maColorHandle);  
         //绘制六角星
         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount); 
    }
}




原文地址:https://www.cnblogs.com/Anzhongliu/p/6092115.html