效果图:
底面:
侧面:
底面圆核心代码:
//初始化顶点数据的方法
public void initVertexData()
{
// 顶点坐标数据的初始化================begin============================
ArrayList<Float> alVertix = new ArrayList<Float>();// 存放顶点坐标的ArrayList
ArrayList<Float> texVertix = new ArrayList<Float>();// 存放纹理坐标
final int angleSpan = 10;
final float UNIT_SIZE=1f;
final float UNIT_SIZE_2=0.3f;
for (int hAngle = 0; hAngle <= 360; hAngle = hAngle + angleSpan)
{
//顶点坐标
float x0 = 0;
float y0 = 0;
float z0= 0;
float z1= (float) (r * UNIT_SIZE * Math.cos(Math.toRadians(hAngle)));
float y1= 0;
float x1= (float) (r * UNIT_SIZE * Math.sin(Math.toRadians(hAngle)));
float z2 = (float) (r * UNIT_SIZE * Math.cos(Math.toRadians(hAngle+ angleSpan)));
float y2= 0;
float x2= (float) (r * UNIT_SIZE * Math.sin(Math.toRadians(hAngle+ angleSpan)));
//纹理坐标
float tex_s=0.5f;
float tex_p=0.5f;
float tex_s1= (float) (UNIT_SIZE_2 * Math.cos(Math.toRadians(hAngle)))+0.5f;
float tex_p1= (float) (UNIT_SIZE_2 * Math.sin(Math.toRadians(hAngle)))+0.5f;
float tex_s2 = (float) (UNIT_SIZE_2 * Math.cos(Math.toRadians(hAngle+ angleSpan)))+0.5f;
float tex_p2= (float) (UNIT_SIZE_2 * Math.sin(Math.toRadians(hAngle+ angleSpan)))+0.5f;
alVertix.add(x0);
alVertix.add(y0);
alVertix.add(z0);
alVertix.add(x1);
alVertix.add(y1);
alVertix.add(z1);
alVertix.add(x2);
alVertix.add(y2);
alVertix.add(z2);
texVertix.add(tex_s);
texVertix.add(tex_p);
texVertix.add(tex_s1);
texVertix.add(tex_p1);
texVertix.add(tex_s2);
texVertix.add(tex_p2);
}
vCount = alVertix.size() / 3;// 顶点的数量为坐标值数量的1/3,因为一个顶点有3个坐标
// 将alVertix中的坐标值转存到一个float数组中
float vertices[] = new float[vCount * 3];
for (int i = 0; i < alVertix.size(); i++) {
vertices[i] = alVertix.get(i);
}
float texCoor[]=new float[vCount * 2];//顶点颜色值数组,每个顶点4个色彩值RGBA
for (int i = 0; i < texVertix.size(); i++) {
texCoor[i] = texVertix.get(i);
}
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
//转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
//顶点坐标数据的初始化================end============================
//顶点纹理坐标数据的初始化================begin============================
//创建顶点纹理坐标数据缓冲
ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点纹理数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
//特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
//转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
//顶点纹理坐标数据的初始化
侧面核心代码:
圆锥侧面展开为扇形,纹理坐标贴图时截取扇形部分。
public void initVertexData()
{
// 顶点坐标数据的初始化================begin============================
ArrayList<Float> texVertix = new ArrayList<Float>();// 存放顶点坐标的ArrayList
ArrayList<Float> alVertix = new ArrayList<Float>();// // 存放纹理坐标
final int angleSpan = 10;//底面圆划分度数
final float wangleSpan = 3.16f;//扇形划分度数
final float UNIT_SIZE=1f;
final float UNIT_SIZE_2=0.5f;//扇形圆心
final int mult_r = 3;
float h=mult_r*r * UNIT_SIZE;
for (int hAngle = 0; hAngle <= 360; hAngle = hAngle + angleSpan)// 水平方向angleSpan度一份
{
float x0 = 0;
float y0 = h;
float z0= 0;
float x1= (float) (r * UNIT_SIZE * Math.cos(Math.toRadians(hAngle)));
float y1= 0;
float z1= (float) (r * UNIT_SIZE * Math.sin(Math.toRadians(hAngle)));
float x2 = (float) (r * UNIT_SIZE * Math.cos(Math.toRadians(hAngle+ angleSpan)));
float y2= 0;
float z2= (float) (r * UNIT_SIZE * Math.sin(Math.toRadians(hAngle+ angleSpan)));
alVertix.add(x2);
alVertix.add(y2);
alVertix.add(z2);
alVertix.add(x1);
alVertix.add(y1);
alVertix.add(z1);
alVertix.add(x0);
alVertix.add(y0);
alVertix.add(z0);
}
for (float vAngle = 33.08f; vAngle <=146.92; vAngle = vAngle + wangleSpan)// 水平方向angleSpan度一份113.84
{
float tex_s0= 0.5f;
float tex_p0= 0.18f;
float tex_s1= (float) (UNIT_SIZE_2* Math.cos(Math.toRadians(vAngle)))+0.5f;
float tex_p1 = (float) (UNIT_SIZE_2* Math.sin(Math.toRadians(vAngle)))+0.18f;
float tex_s2= (float) (UNIT_SIZE_2 * Math.cos(Math.toRadians(vAngle + wangleSpan)))+0.5f;
float tex_p2 = (float) (UNIT_SIZE_2 * Math.sin(Math.toRadians(vAngle + wangleSpan)))+0.18f;
texVertix.add(tex_s2);
texVertix.add(tex_p2);
texVertix.add(tex_s1);
texVertix.add(tex_p1);
texVertix.add(tex_s0);
texVertix.add(tex_p0);
}
vCount = alVertix.size() / 3;// 顶点的数量为坐标值数量的1/3,因为一个顶点有3个坐标
// 将alVertix中的坐标值转存到一个float数组中
float vertices[] = new float[vCount * 3];
for (int i = 0; i < alVertix.size(); i++) {
vertices[i] = alVertix.get(i);
}
float texCoor[]=new float[vCount * 2];//顶点颜色值数组,每个顶点4个色彩值RGBA
for (int i = 0; i < texVertix.size(); i++) {
texCoor[i] = texVertix.get(i);
}
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
//转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
//顶点坐标数据的初始化================end============================
//顶点纹理坐标数据的初始化================begin============================
//创建顶点纹理坐标数据缓冲
ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点纹理数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
//特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer
//转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题
//顶点纹理坐标数据的初始化================end============================
}