freeglut中提供的几种立体几何对象绘制的android移植

在freeglut_geometry.c中定义了几种常见图形的绘制,包括立方体, 球面, 圆锥体, 圆柱体, 圆环面, 十二面体, 八面体, 四面体, 二十面体, 菱形十二面体(斜十二面体)等几种立体几何对象的绘制。 移植后的Android Java代码如下所示:

 

/**
 * fyjengine All Rights Reserved
 *
 * @author Yajun Fu  
 * 2011-11-4
 *
 * porting functions from freeglut
 */
package fyj.engine.utils;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

public class FreeGLUT {

	/*
	 * 立方体(线框)
	 */
	public static void glutWireCube(GL10 gl, float dSize) {

		float size = dSize * 0.5f;

		ByteBuffer bb = ByteBuffer.allocateDirect(24 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertexBuffer = bb.asFloatBuffer();
		vertexBuffer.position(0);

		bb = ByteBuffer.allocateDirect(24 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normalBuffer = bb.asFloatBuffer();
		normalBuffer.position(0);

		vertexBuffer.put(new float[] { +size, -size, +size, +size, -size,
				-size, +size, +size, -size, +size, +size, +size,

				+size, +size, +size, +size, +size, -size, -size, +size, -size,
				-size, +size, +size,

				+size, +size, +size, -size, +size, +size, -size, -size, +size,
				+size, -size, +size,

				-size, -size, +size, -size, +size, +size, -size, +size, -size,
				-size, -size, -size,

				-size, -size, +size, -size, -size, -size, +size, -size, -size,
				+size, -size, +size,

				-size, -size, -size, -size, +size, -size, +size, +size, -size,
				+size, -size, -size });
		normalBuffer.put(new float[] { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
				1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,

				0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
				1.0f, 0.0f,

				0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
				0.0f, 1.0f,

				-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
				0.0f, 0.0f,

				0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
				-1.0f, 0.0f,

				0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
				0.0f, -1.0f,

		});

		vertexBuffer.position(0);
		normalBuffer.position(0);
		gl.glColor4f(1, 0, 0, 1);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normalBuffer);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		for (int i = 0; i < 6; i++)
			gl.glDrawArrays(GL10.GL_LINE_LOOP, 4 * i, 4);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

	}

	/*
	 * 立方体
	 */
	public static void glutSolidCube(GL10 gl, float dSize) {
		float size = dSize * 0.5f;

		ByteBuffer bb = ByteBuffer.allocateDirect(24 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertexBuffer = bb.asFloatBuffer();
		vertexBuffer.position(0);

		bb = ByteBuffer.allocateDirect(24 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normalBuffer = bb.asFloatBuffer();
		normalBuffer.position(0);

		vertexBuffer.put(new float[] { +size, -size, +size, +size, -size,
				-size, +size, +size, -size, +size, +size, +size,

				+size, +size, +size, +size, +size, -size, -size, +size, -size,
				-size, +size, +size,

				+size, +size, +size, -size, +size, +size, -size, -size, +size,
				+size, -size, +size,

				-size, -size, +size, -size, +size, +size, -size, +size, -size,
				-size, -size, -size,

				-size, -size, +size, -size, -size, -size, +size, -size, -size,
				+size, -size, +size,

				-size, -size, -size, -size, +size, -size, +size, +size, -size,
				+size, -size, -size });
		normalBuffer.put(new float[] { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
				1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,

				0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
				1.0f, 0.0f,

				0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
				0.0f, 1.0f,

				-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
				0.0f, 0.0f,

				0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
				-1.0f, 0.0f,

				0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
				0.0f, -1.0f, });

		vertexBuffer.position(0);
		normalBuffer.position(0);

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normalBuffer);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		for (int i = 0; i < 6; i++)
			gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 4 * i, 4);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

		bb.clear();
		vertexBuffer.clear();
		normalBuffer.clear();
	}

	private static void fghCircleTable(float sint[], float cost[], int n) {
		int i;

		/* Table size, the sign of n flips the circle direction */

		int size = Math.abs(n);

		/* Determine the angle between samples */

		float angle = (float) (2 * Math.PI / (float) ((n == 0) ? 1 : n));

		/* Compute cos and sin around the circle */

		sint[0] = 0.0f;
		cost[0] = 1.0f;
		for (i = 1; i < size; i++) {
			sint[i] = (float) Math.sin(angle * i);
			cost[i] = (float) Math.cos(angle * i);
		}

		/* Last sample is duplicate of the first */

		sint[size] = sint[0];
		cost[size] = cost[0];
	}

	/*
	 * 球面(线框)
	 */
	public static void glutWireSphere(GL10 gl, float radius, int slices,
			int stacks) {
		int i, j;

		/* Adjust z and radius as stacks and slices are drawn. */

		float r;
		float x, y, z;

		/* Pre-computed circle */

		float sint1[] = new float[slices + 1], cost1[] = new float[slices + 1];
		float sint2[] = new float[stacks * 2 + 1], cost2[] = new float[stacks * 2 + 1];

		fghCircleTable(sint1, cost1, -slices);
		fghCircleTable(sint2, cost2, stacks * 2);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

		ByteBuffer bb = ByteBuffer.allocateDirect((slices + 1) * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normals = bb.asFloatBuffer();
		normals.position(0);

		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		/* Draw a line loop for each stack */

		for (i = 1; i < stacks; i++) {
			z = cost2[i];
			r = sint2[i];

			for (j = 0; j <= slices; j++) {
				x = cost1[j];
				y = sint1[j];

				normals.put(new float[] { x, y, z });
				vertex.put(new float[] { x * r * radius, y * r * radius,
						z * radius });
			}

			normals.position(0);
			vertex.position(0);
			gl.glNormalPointer(GL10.GL_FLOAT, 0, normals);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
			gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, slices + 1);

		}

		/* Draw a line loop for each slice */

		bb = ByteBuffer.allocateDirect((stacks + 1) * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		vertex = bb.asFloatBuffer();
		vertex.position(0);
		normals = bb.asFloatBuffer();
		normals.position(0);

		for (i = 0; i < slices; i++) {

			for (j = 0; j <= stacks; j++) {
				x = cost1[i] * sint2[j];
				y = sint1[i] * sint2[j];
				z = cost2[j];

				normals.put(new float[] { x, y, z });
				vertex.put(new float[] { x * radius, y * radius, z * radius });
			}
			normals.position(0);
			vertex.position(0);
			gl.glNormalPointer(GL10.GL_FLOAT, 0, normals);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
			gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, stacks + 1);
		}

		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	/*
	 * 球面
	 */
	public static void glutSolidSphere(GL10 gl, float radius, int slices,
			int stacks) {
		int i, j;

		/* Adjust z and radius as stacks are drawn. */

		float z0, z1;
		float r0, r1;

		/* Pre-computed circle */

		float sint1[] = new float[slices + 1], cost1[] = new float[slices + 1];
		float sint2[] = new float[stacks * 2 + 1], cost2[] = new float[stacks * 2 + 1];

		fghCircleTable(sint1, cost1, -slices);
		fghCircleTable(sint2, cost2, stacks * 2);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

		/* The top stack is covered with a triangle fan */

		z0 = 1.0f;
		z1 = cost2[(stacks > 0) ? 1 : 0];
		r0 = 0.0f;
		r1 = sint2[(stacks > 0) ? 1 : 0];

		ByteBuffer bb = ByteBuffer.allocateDirect((slices + 2) * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normals = bb.asFloatBuffer();
		normals.position(0);

		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		normals.put(new float[] { 0, 0, 1 });
		vertex.put(new float[] { 0, 0, radius });

		for (j = slices; j >= 0; j--) {
			normals.put(new float[] { cost1[j] * r1, sint1[j] * r1, z1 });
			vertex.put(new float[] { cost1[j] * r1 * radius,
					sint1[j] * r1 * radius, z1 * radius });
		}
		vertex.position(0);
		normals.position(0);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normals);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, slices + 2);

		bb = ByteBuffer.allocateDirect((slices + 1) * 3 * 2 * 4);
		bb.order(ByteOrder.nativeOrder());
		normals = bb.asFloatBuffer();
		vertex = bb.asFloatBuffer();
		/* Cover each stack with a quad strip, except the top and bottom stacks */

		for (i = 1; i < stacks - 1; i++) {
			z0 = z1;
			z1 = cost2[i + 1];
			r0 = r1;
			r1 = sint2[i + 1];

			normals.position(0);
			vertex.position(0);

			for (j = 0; j <= slices; j++) {
				normals.put(new float[] { cost1[j] * r1, sint1[j] * r1, z1 });
				vertex.put(new float[] { cost1[j] * r1 * radius,
						sint1[j] * r1 * radius, z1 * radius });
				normals.put(new float[] { cost1[j] * r0, sint1[j] * r0, z0 });
				vertex.put(new float[] { cost1[j] * r0 * radius,
						sint1[j] * r0 * radius, z0 * radius });
			}
			vertex.position(0);
			normals.position(0);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
			gl.glNormalPointer(GL10.GL_FLOAT, 0, normals);
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, (slices + 1) * 2);
		}

		/* The bottom stack is covered with a triangle fan */

		z0 = z1;
		r0 = r1;

		bb = ByteBuffer.allocateDirect((slices + 2) * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		normals = bb.asFloatBuffer();
		normals.position(0);
		vertex = bb.asFloatBuffer();
		vertex.position(0);

		normals.put(new float[] { 0, 0, -1 });
		vertex.put(new float[] { 0, 0, -radius });

		for (j = 0; j <= slices; j++) {
			normals.put(new float[] { cost1[j] * r0, sint1[j] * r0, z0 });
			vertex.put(new float[] { cost1[j] * r0 * radius,
					sint1[j] * r0 * radius, z0 * radius });
		}
		vertex.position(0);
		normals.position(0);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normals);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, slices + 2);

		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	/*
	 * 圆锥体(线框)
	 */
	public static void glutWireCone(GL10 gl, float base, float height,
			int slices, int stacks) {
		int i, j;

		/* Step in z and radius as stacks are drawn. */

		float z = 0.0f;
		float r = base;

		float zStep = height / ((stacks > 0) ? stacks : 1);
		float rStep = base / ((stacks > 0) ? stacks : 1);

		/* Scaling factors for vertex normals */
		float cosn = (height / (float) Math.sqrt(height * height + base * base));
		float sinn = (base / (float) Math.sqrt(height * height + base * base));

		/* Pre-computed circle */
		float sint[] = new float[slices + 1], cost[] = new float[slices + 1];
		fghCircleTable(sint, cost, -slices);

		/* Draw the stacks... */
		ByteBuffer bb = ByteBuffer.allocateDirect(slices * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

		for (i = 0; i < stacks; i++) {

			for (j = 0; j < slices; j++) {
				normal.put(new float[] { cost[j] * sinn, sint[j] * sinn, cosn });
				vertex.put(new float[] { cost[j] * r, sint[j] * r, z });
			}

			normal.position(0);
			vertex.position(0);
			gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
			gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, slices);

			z += zStep;
			r -= rStep;
		}

		/* Draw the slices */

		r = base;

		bb = ByteBuffer.allocateDirect(slices * 2 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		vertex = bb.asFloatBuffer();
		vertex.position(0);

		normal.position(0);

		for (j = 0; j < slices; j++) {
			normal.put(new float[] { cost[j] * sinn, sint[j] * sinn, cosn });
			vertex.put(new float[] { cost[j] * r, sint[j] * r, 0.0f, 0.0f,
					0.0f, height });
		}

		vertex.position(0);
		normal.position(0);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_LINES, 0, slices);

		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
	}

	/*
	 * 圆锥体
	 */
	public static void glutSolidCone(GL10 gl, float base, float height,
			int slices, int stacks) {
		int i, j;

		/* Step in z and radius as stacks are drawn. */

		float z0, z1;
		float r0, r1;

		float zStep = height / ((stacks > 0) ? stacks : 1);
		float rStep = base / ((stacks > 0) ? stacks : 1);

		/* Scaling factors for vertex normals */

		float cosn = (height / (float) Math.sqrt(height * height + base * base));
		float sinn = (base / (float) Math.sqrt(height * height + base * base));

		/* Pre-computed circle */
		float sint[] = new float[slices + 2], cost[] = new float[slices + 2];
		fghCircleTable(sint, cost, -slices);

		/* Cover the circular base with a triangle fan... */
		z0 = 0.0f;
		z1 = zStep;

		r0 = base;
		r1 = r0 - rStep;

		ByteBuffer bb = ByteBuffer.allocateDirect((slices + 2) * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);
		bb = ByteBuffer.allocateDirect(3 * 4);
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);

		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

		normal.put(new float[] { 0.0f, 0.0f, -1.0f });
		vertex.put(new float[] { 0.0f, 0.0f, z0 });

		for (j = 0; j <= slices; j++)
			vertex.put(new float[] { cost[j] * r0, sint[j] * r0, z0 });
		normal.position(0);
		vertex.position(0);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, slices + 2);

		/* Cover each stack with a quad strip, except the top stack */
		bb = ByteBuffer.allocateDirect((slices + 1) * 2 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		vertex = bb.asFloatBuffer();
		vertex.position(0);
		bb = ByteBuffer.allocateDirect((slices + 1) * 3 * 4);
		normal = bb.asFloatBuffer();
		normal.position(0);
		for (i = 0; i < stacks - 1; i++) {

			for (j = 0; j <= slices; j++) {
				normal.put(new float[] { cost[j] * sinn, sint[j] * sinn, cosn });
				vertex.put(new float[] { cost[j] * r0, sint[j] * r0, z0,
						cost[j] * r1, sint[j] * r1, z1 });
			}

			vertex.position(0);
			normal.position(0);
			gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, (slices + 1) * 2);

			z0 = z1;
			z1 += zStep;
			r0 = r1;
			r1 -= rStep;

		}

		/* The top stack is covered with individual triangles */
		bb = ByteBuffer.allocateDirect(slices * 3 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		vertex = bb.asFloatBuffer();
		vertex.position(0);
		bb = ByteBuffer.allocateDirect((slices + 1) * 3 * 4);
		normal = bb.asFloatBuffer();
		normal.position(0);

		normal.put(new float[] { cost[0] * sinn, sint[0] * sinn, cosn });

		for (j = 0; j < slices; j++) {
			vertex.put(new float[] { cost[j + 0] * r0, sint[j + 0] * r0, z0, 0,
					0, height, cost[j + 1] * r0, sint[j + 1] * r0, z0 });
			normal.put(new float[] { cost[j + 1] * sinn, sint[j + 1] * sinn,
					cosn });
		}
		vertex.position(0);
		normal.position(0);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, slices * 3);

		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

	}

	/*
	 * 圆柱体(线框)
	 */
	public static void glutWireCylinder(GL10 gl, float radius, float height,
			int slices, int stacks) {
		int i, j;

		/* Step in z and radius as stacks are drawn. */
		float z = 0.0f;
		float zStep = height / ((stacks > 0) ? stacks : 1);

		/* Pre-computed circle */
		float sint[] = new float[slices + 1], cost[] = new float[slices + 1];
		fghCircleTable(sint, cost, -slices);
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

		/* Draw the stacks... */
		ByteBuffer bb = ByteBuffer.allocateDirect(slices * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);

		for (i = 0; i <= stacks; i++) {
			if (i == stacks)
				z = height;

			for (j = 0; j < slices; j++) {
				normal.put(new float[] { cost[j], sint[j], 0.0f });
				vertex.put(new float[] { cost[j] * radius, sint[j] * radius, z });
			}
			normal.position(0);
			vertex.position(0);
			gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
			gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, slices);
			
			z += zStep;
		}
		
	    /* Draw the slices */
		bb = ByteBuffer.allocateDirect(slices * 2 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		vertex = bb.asFloatBuffer();
		vertex.position(0);
		bb = ByteBuffer.allocateDirect(slices * 3 * 4);
		normal = bb.asFloatBuffer();
		normal.position(0);

        for (j=0; j<slices; j++)
        {
        	normal.put(new float[] {
        			cost[j],        sint[j],        0.0f
        	});
        	vertex.put(new float[] {
        		cost[j]*radius, sint[j]*radius, 0.0f,
        		cost[j]*radius, sint[j]*radius, height
        	});
        }
        
        normal.position(0);
        vertex.position(0);
        gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glDrawArrays(GL10.GL_LINES, 0, slices);
        
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
	        
	}

	/*
	 * 圆柱体
	 */
	public static void glutSolidCylinder(GL10 gl, float radius, float height,
			int slices, int stacks) {
		int i, j;

		/* Step in z and radius as stacks are drawn. */
		float z0, z1;
		float zStep = height / ((stacks > 0) ? stacks : 1);

	    /* Pre-computed circle */
		float sint[] = new float[slices + 2], cost[] = new float[slices + 2];
		fghCircleTable(sint, cost, -slices);
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

	    /* Cover the base and top */
		ByteBuffer bb = ByteBuffer.allocateDirect((slices+2) * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);
		bb = ByteBuffer.allocateDirect(3 * 4);
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);
		
		normal.put(new float[] {
				0.0f, 0.0f, -1.0f
		});
		vertex.put(new float[] {
				0.0f, 0.0f,  0.0f
		});

        for (j=0; j<=slices; j++)
    		vertex.put(new float[] {
    				cost[j]*radius, sint[j]*radius, 0.0f
    		});
        vertex.position(0);
        normal.position(0);
        gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, slices+2);

        vertex.position(0);
        normal.position(0);
        
		normal.put(new float[] {
				0.0f, 0.0f, 1.0f
		});
		vertex.put(new float[] {
				0.0f, 0.0f,  height
		});

        for (j=slices; j>=0; j--)
    		vertex.put(new float[] {
    				cost[j]*radius, sint[j]*radius, height
    		});
        vertex.position(0);
        normal.position(0);
        gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
        gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, slices+2);

	    /* Do the stacks */
	    z0 = 0.0f;
	    z1 = zStep;

		bb = ByteBuffer.allocateDirect((slices+1) * 2 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		vertex = bb.asFloatBuffer();
		vertex.position(0);
		bb = ByteBuffer.allocateDirect((slices+1) * 3 * 4);
		normal = bb.asFloatBuffer();
		normal.position(0);
	    for (i=1; i<=stacks; i++)
	    {
	        if (i==stacks)
	            z1 = height;

	            for (j=0; j<=slices; j++ )
	            {
	            	normal.put(new float[] {
	            			cost[j],        sint[j],        0.0f
	            	});
	            	vertex.put(new float[] {
	            			cost[j]*radius, sint[j]*radius, z0,
	            			cost[j]*radius, sint[j]*radius, z1
	            	});
	            }

	        normal.position(0);
	        vertex.position(0);
	        gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
	        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
	        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, (slices+1) * 2);

	        z0 = z1; z1 += zStep;
	    }
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
	}

	/*
	 * 圆环面(线框)
	 */
	public static void glutWireTorus(GL10 gl, float dInnerRadius,
			float dOuterRadius, int nSides, int nRings) {
		float iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
		FloatBuffer vertex, normal;

		int i, j;
		float spsi, cpsi, sphi, cphi;

		if (nSides < 1)
			nSides = 1;
		if (nRings < 1)
			nRings = 1;

		/*
		 * Increment the number of sides and rings to allow for one more point
		 * than surface
		 */
		nSides++;
		nRings++;

		float vertexArray[] = new float[3 * nSides * nRings];
		float normalArray[] = new float[3 * nSides * nRings];

		gl.glPushMatrix();
		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		dpsi = 2.0f * (float) Math.PI / (float) (nRings - 1);
		dphi = -2.0f * (float) Math.PI / (float) (nSides - 1);
		psi = 0.0f;

		for (j = 0; j < nRings; j++) {
			cpsi = (float) Math.cos(psi);
			spsi = (float) Math.sin(psi);
			phi = 0.0f;

			for (i = 0; i < nSides; i++) {
				int offset = 3 * (j * nSides + i);
				cphi = (float) Math.cos(phi);
				sphi = (float) Math.sin(phi);
				vertexArray[offset + 0] = cpsi * (oradius + cphi * iradius);
				vertexArray[offset + 1] = spsi * (oradius + cphi * iradius);
				vertexArray[offset + 2] = sphi * iradius;

				normalArray[offset + 0] = cpsi * cphi;
				normalArray[offset + 1] = spsi * cphi;
				normalArray[offset + 2] = sphi;

				phi += dphi;
			}

			psi += dpsi;
		}

		ByteBuffer bb = ByteBuffer.allocateDirect((nSides - 1) * (nRings - 1)
				* 4 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		vertex = bb.asFloatBuffer();
		vertex.position(0);

		normal = bb.asFloatBuffer();
		normal.position(0);

		for (i = 0; i < nSides - 1; i++) {
			for (j = 0; j < nRings - 1; j++) {
				int offset = 3 * (j * nSides + i);
				normal.put(new float[] { normalArray[offset],
						normalArray[offset + 1], normalArray[offset + 2],
						normalArray[offset + 3], normalArray[offset + 4],
						normalArray[offset + 5],
						normalArray[offset + 3 * nSides + 3],
						normalArray[offset + 3 * nSides + 4],
						normalArray[offset + 3 * nSides + 5],
						normalArray[offset + 3 * nSides],
						normalArray[offset + 3 * nSides + 1],
						normalArray[offset + 3 * nSides + 2] });

				vertex.put(new float[] { vertexArray[offset],
						vertexArray[offset + 1], vertexArray[offset + 2],
						vertexArray[offset + 3], vertexArray[offset + 4],
						vertexArray[offset + 5],
						vertexArray[offset + 3 * nSides + 3],
						vertexArray[offset + 3 * nSides + 4],
						vertexArray[offset + 3 * nSides + 5],
						vertexArray[offset + 3 * nSides],
						vertexArray[offset + 3 * nSides + 1],
						vertexArray[offset + 3 * nSides + 2] });
			}
		}

		vertex.position(0);
		normal.position(0);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, (nSides - 1) * (nRings - 1) * 4);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glPopMatrix();
	}

	/*
	 * 圆环面
	 */
	public static void glutSolidTorus(GL10 gl, float dInnerRadius,
			float dOuterRadius, int nSides, int nRings) {
		float iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
		FloatBuffer vertex, normal;

		int i, j;
		float spsi, cpsi, sphi, cphi;

		if (nSides < 1)
			nSides = 1;
		if (nRings < 1)
			nRings = 1;

		/*
		 * Increment the number of sides and rings to allow for one more point
		 * than surface
		 */
		nSides++;
		nRings++;

		float vertexArray[] = new float[3 * nSides * nRings];
		float normalArray[] = new float[3 * nSides * nRings];

		gl.glPushMatrix();
		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		dpsi = 2.0f * (float) Math.PI / (float) (nRings - 1);
		dphi = -2.0f * (float) Math.PI / (float) (nSides - 1);
		psi = 0.0f;

		for (j = 0; j < nRings; j++) {
			cpsi = (float) Math.cos(psi);
			spsi = (float) Math.sin(psi);
			phi = 0.0f;

			for (i = 0; i < nSides; i++) {
				int offset = 3 * (j * nSides + i);
				cphi = (float) Math.cos(phi);
				sphi = (float) Math.sin(phi);
				vertexArray[offset + 0] = cpsi * (oradius + cphi * iradius);
				vertexArray[offset + 1] = spsi * (oradius + cphi * iradius);
				vertexArray[offset + 2] = sphi * iradius;

				normalArray[offset + 0] = cpsi * cphi;
				normalArray[offset + 1] = spsi * cphi;
				normalArray[offset + 2] = sphi;

				phi += dphi;
			}

			psi += dpsi;
		}

		ByteBuffer bb = ByteBuffer.allocateDirect((nSides - 1) * (nRings - 1)
				* 4 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		vertex = bb.asFloatBuffer();
		vertex.position(0);

		normal = bb.asFloatBuffer();
		normal.position(0);

		for (i = 0; i < nSides - 1; i++) {
			for (j = 0; j < nRings - 1; j++) {
				int offset = 3 * (j * nSides + i);
				normal.put(new float[] { normalArray[offset + 3 * nSides],
						normalArray[offset + 3 * nSides + 1],
						normalArray[offset + 3 * nSides + 2],
						normalArray[offset], vertexArray[offset + 1],
						normalArray[offset + 2],
						normalArray[offset + 3 * nSides + 3],
						normalArray[offset + 3 * nSides + 4],
						normalArray[offset + 3 * nSides + 5],
						normalArray[offset + 3], vertexArray[offset + 4],
						normalArray[offset + 5] });

				vertex.put(new float[] { vertexArray[offset + 3 * nSides],
						vertexArray[offset + 3 * nSides + 1],
						vertexArray[offset + 3 * nSides + 2],
						vertexArray[offset], vertexArray[offset + 1],
						vertexArray[offset + 2],
						vertexArray[offset + 3 * nSides + 3],
						vertexArray[offset + 3 * nSides + 4],
						vertexArray[offset + 3 * nSides + 5],
						vertexArray[offset + 3], vertexArray[offset + 4],
						vertexArray[offset + 5] });
			}
		}

		vertex.position(0);
		normal.position(0);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, (nSides - 1) * (nRings - 1)
				* 4);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glPopMatrix();
	}

	/*
	 * 十二面体(线框)
	 */
	public static void glutWireDodecahedron(GL10 gl) {
		/*
		 * Magic Numbers: It is possible to create a dodecahedron by attaching
		 * two pentagons to each face of of a cube. The coordinates of the
		 * points are: (+-x,0, z); (+-1, 1, 1); (0, z, x ) where x = (-1 +
		 * sqrt(5))/2, z = (1 + sqrt(5))/2 or x = 0.61803398875 and z =
		 * 1.61803398875.
		 */
		ByteBuffer bb = ByteBuffer.allocateDirect(12 * 5 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		vertex.put(new float[] { 0.0f, 1.61803398875f, 0.61803398875f, -1.0f,
				1.0f, 1.0f, -0.61803398875f, 0.0f, 1.61803398875f,
				0.61803398875f, 0.0f, 1.61803398875f, 1.0f, 1.0f, 1.0f,

				0.0f, 1.61803398875f, -0.61803398875f, 1.0f, 1.0f, -1.0f,
				0.61803398875f, 0.0f, -1.61803398875f, -0.61803398875f, 0.0f,
				-1.61803398875f, -1.0f, 1.0f, -1.0f,

				0.0f, -1.61803398875f, 0.61803398875f, 1.0f, -1.0f, 1.0f,
				0.61803398875f, 0.0f, 1.61803398875f, -0.61803398875f, 0.0f,
				1.61803398875f, -1.0f, -1.0f, 1.0f,

				0.0f, -1.61803398875f, -0.61803398875f, -1.0f, -1.0f, -1.0f,
				-0.61803398875f, 0.0f, -1.61803398875f, 0.61803398875f, 0.0f,
				-1.61803398875f, 1.0f, -1.0f, -1.0f,

				0.61803398875f, 0.0f, 1.61803398875f, 1.0f, -1.0f, 1.0f,
				1.61803398875f, -0.61803398875f, 0.0f, 1.61803398875f,
				0.61803398875f, 0.0f, 1.0f, 1.0f, 1.0f,

				-0.61803398875f, 0.0f, 1.61803398875f, -1.0f, 1.0f, 1.0f,
				-1.61803398875f, 0.61803398875f, 0.0f, -1.61803398875f,
				-0.61803398875f, 0.0f, -1.0f, -1.0f, 1.0f,

				0.61803398875f, 0.0f, -1.61803398875f, 1.0f, 1.0f, -1.0f,
				1.61803398875f, 0.61803398875f, 0.0f, 1.61803398875f,
				-0.61803398875f, 0.0f, 1.0f, -1.0f, -1.0f,

				-0.61803398875f, 0.0f, -1.61803398875f, -1.0f, -1.0f, -1.0f,
				-1.61803398875f, -0.61803398875f, 0.0f, -1.61803398875f,
				0.61803398875f, 0.0f, -1.0f, 1.0f, -1.0f,

				1.61803398875f, 0.61803398875f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f,
				1.61803398875f, -0.61803398875f, 0.0f, 1.61803398875f,
				0.61803398875f, 1.0f, 1.0f, 1.0f,

				1.61803398875f, -0.61803398875f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f,
				-1.61803398875f, 0.61803398875f, 0.0f, -1.61803398875f,
				-0.61803398875f, 1.0f, -1.0f, -1.0f,

				-1.61803398875f, 0.61803398875f, 0.0f, -1.0f, 1.0f, 1.0f, 0.0f,
				1.61803398875f, 0.61803398875f, 0.0f, 1.61803398875f,
				-0.61803398875f, -1.0f, 1.0f, -1.0f,

				-1.61803398875f, -0.61803398875f, 0.0f, -1.0f, -1.0f, -1.0f,
				0.0f, -1.61803398875f, -0.61803398875f, 0.0f, -1.61803398875f,
				0.61803398875f, -1.0f, -1.0f, 1.0f

		});
		vertex.position(0);

		bb = ByteBuffer.allocateDirect(12 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);
		normal.put(new float[] { 0.0f, 0.525731112119f, 0.850650808354f, 0.0f,
				0.525731112119f, -0.850650808354f, 0.0f, -0.525731112119f,
				0.850650808354f, 0.0f, -0.525731112119f, -0.850650808354f,
				0.850650808354f, 0.0f, 0.525731112119f, -0.850650808354f, 0.0f,
				0.525731112119f, 0.850650808354f, 0.0f, -0.525731112119f,
				-0.850650808354f, 0.0f, -0.525731112119f, 0.525731112119f,
				0.850650808354f, 0.0f, 0.525731112119f, -0.850650808354f, 0.0f,
				-0.525731112119f, 0.850650808354f, 0.0f, -0.525731112119f,
				-0.850650808354f, 0.0f });
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		for (int i = 0; i < 12; i++)
			gl.glDrawArrays(GL10.GL_LINE_LOOP, 5 * i, 5);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

	}

	/*
	 * 十二面体
	 */
	public static void glutSolidDodecahedron(GL10 gl) {
		/*
		 * Magic Numbers: It is possible to create a dodecahedron by attaching
		 * two pentagons to each face of of a cube. The coordinates of the
		 * points are: (+-x,0, z); (+-1, 1, 1); (0, z, x ) where x = (-1 +
		 * sqrt(5))/2, z = (1 + sqrt(5))/2 or x = 0.61803398875 and z =
		 * 1.61803398875.
		 */
		ByteBuffer bb = ByteBuffer.allocateDirect(12 * 5 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		vertex.put(new float[] { 0.0f, 1.61803398875f, 0.61803398875f, -1.0f,
				1.0f, 1.0f, -0.61803398875f, 0.0f, 1.61803398875f,
				0.61803398875f, 0.0f, 1.61803398875f, 1.0f, 1.0f, 1.0f,

				0.0f, 1.61803398875f, -0.61803398875f, 1.0f, 1.0f, -1.0f,
				0.61803398875f, 0.0f, -1.61803398875f, -0.61803398875f, 0.0f,
				-1.61803398875f, -1.0f, 1.0f, -1.0f,

				0.0f, -1.61803398875f, 0.61803398875f, 1.0f, -1.0f, 1.0f,
				0.61803398875f, 0.0f, 1.61803398875f, -0.61803398875f, 0.0f,
				1.61803398875f, -1.0f, -1.0f, 1.0f,

				0.0f, -1.61803398875f, -0.61803398875f, -1.0f, -1.0f, -1.0f,
				-0.61803398875f, 0.0f, -1.61803398875f, 0.61803398875f, 0.0f,
				-1.61803398875f, 1.0f, -1.0f, -1.0f,

				0.61803398875f, 0.0f, 1.61803398875f, 1.0f, -1.0f, 1.0f,
				1.61803398875f, -0.61803398875f, 0.0f, 1.61803398875f,
				0.61803398875f, 0.0f, 1.0f, 1.0f, 1.0f,

				-0.61803398875f, 0.0f, 1.61803398875f, -1.0f, 1.0f, 1.0f,
				-1.61803398875f, 0.61803398875f, 0.0f, -1.61803398875f,
				-0.61803398875f, 0.0f, -1.0f, -1.0f, 1.0f,

				0.61803398875f, 0.0f, -1.61803398875f, 1.0f, 1.0f, -1.0f,
				1.61803398875f, 0.61803398875f, 0.0f, 1.61803398875f,
				-0.61803398875f, 0.0f, 1.0f, -1.0f, -1.0f,

				-0.61803398875f, 0.0f, -1.61803398875f, -1.0f, -1.0f, -1.0f,
				-1.61803398875f, -0.61803398875f, 0.0f, -1.61803398875f,
				0.61803398875f, 0.0f, -1.0f, 1.0f, -1.0f,

				1.61803398875f, 0.61803398875f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f,
				1.61803398875f, -0.61803398875f, 0.0f, 1.61803398875f,
				0.61803398875f, 1.0f, 1.0f, 1.0f,

				1.61803398875f, -0.61803398875f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f,
				-1.61803398875f, 0.61803398875f, 0.0f, -1.61803398875f,
				-0.61803398875f, 1.0f, -1.0f, -1.0f,

				-1.61803398875f, 0.61803398875f, 0.0f, -1.0f, 1.0f, 1.0f, 0.0f,
				1.61803398875f, 0.61803398875f, 0.0f, 1.61803398875f,
				-0.61803398875f, -1.0f, 1.0f, -1.0f,

				-1.61803398875f, -0.61803398875f, 0.0f, -1.0f, -1.0f, -1.0f,
				0.0f, -1.61803398875f, -0.61803398875f, 0.0f, -1.61803398875f,
				0.61803398875f, -1.0f, -1.0f, 1.0f

		});
		vertex.position(0);

		bb = ByteBuffer.allocateDirect(12 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);
		normal.put(new float[] { 0.0f, 0.525731112119f, 0.850650808354f, 0.0f,
				0.525731112119f, -0.850650808354f, 0.0f, -0.525731112119f,
				0.850650808354f, 0.0f, -0.525731112119f, -0.850650808354f,
				0.850650808354f, 0.0f, 0.525731112119f, -0.850650808354f, 0.0f,
				0.525731112119f, 0.850650808354f, 0.0f, -0.525731112119f,
				-0.850650808354f, 0.0f, -0.525731112119f, 0.525731112119f,
				0.850650808354f, 0.0f, 0.525731112119f, -0.850650808354f, 0.0f,
				-0.525731112119f, 0.850650808354f, 0.0f, -0.525731112119f,
				-0.850650808354f, 0.0f });
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		for (int i = 0; i < 12; i++)
			gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 5 * i, 5);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	/*
	 * 八面体(线框)
	 */
	public static void glutWireOctahedron(GL10 gl) {
		float RADIUS = 1.0f;
		ByteBuffer bb = ByteBuffer.allocateDirect(8 * 3 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		vertex.put(new float[] { RADIUS, 0.0f, 0.0f, 0.0f, RADIUS, 0.0f, 0.0f,
				0.0f, RADIUS,

				RADIUS, 0.0f, 0.0f, 0.0f, 0.0f, -RADIUS, 0.0f, RADIUS, 0.0f,

				RADIUS, 0.0f, 0.0f, 0.0f, 0.0f, RADIUS, 0.0f, -RADIUS, 0.0f,

				RADIUS, 0.0f, 0.0f, 0.0f, -RADIUS, 0.0f, 0.0f, 0.0f, -RADIUS,

				-RADIUS, 0.0f, 0.0f, 0.0f, 0.0f, RADIUS, 0.0f, RADIUS, 0.0f,

				-RADIUS, 0.0f, 0.0f, 0.0f, RADIUS, 0.0f, 0.0f, 0.0f, -RADIUS,

				-RADIUS, 0.0f, 0.0f, 0.0f, -RADIUS, 0.0f, 0.0f, 0.0f, RADIUS,

				-RADIUS, 0.0f, 0.0f, 0.0f, 0.0f, -RADIUS, 0.0f, -RADIUS, 0.0f

		});
		vertex.position(0);

		bb = ByteBuffer.allocateDirect(8 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);
		normal.put(new float[] { 0.577350269189f, 0.577350269189f,
				0.577350269189f, 0.577350269189f, 0.577350269189f,
				-0.577350269189f, 0.577350269189f, -0.577350269189f,
				0.577350269189f, 0.577350269189f, -0.577350269189f,
				-0.577350269189f, -0.577350269189f, 0.577350269189f,
				0.577350269189f, -0.577350269189f, 0.577350269189f,
				-0.577350269189f, -0.577350269189f, -0.577350269189f,
				0.577350269189f, -0.577350269189f, -0.577350269189f,
				-0.577350269189f });
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 24);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	/*
	 * 八面体
	 */
	public static void glutSolidOctahedron(GL10 gl) {
		float RADIUS = 1.0f;
		ByteBuffer bb = ByteBuffer.allocateDirect(8 * 3 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		vertex.put(new float[] { RADIUS, 0.0f, 0.0f, 0.0f, RADIUS, 0.0f, 0.0f,
				0.0f, RADIUS,

				RADIUS, 0.0f, 0.0f, 0.0f, 0.0f, -RADIUS, 0.0f, RADIUS, 0.0f,

				RADIUS, 0.0f, 0.0f, 0.0f, 0.0f, RADIUS, 0.0f, -RADIUS, 0.0f,

				RADIUS, 0.0f, 0.0f, 0.0f, -RADIUS, 0.0f, 0.0f, 0.0f, -RADIUS,

				-RADIUS, 0.0f, 0.0f, 0.0f, 0.0f, RADIUS, 0.0f, RADIUS, 0.0f,

				-RADIUS, 0.0f, 0.0f, 0.0f, RADIUS, 0.0f, 0.0f, 0.0f, -RADIUS,

				-RADIUS, 0.0f, 0.0f, 0.0f, -RADIUS, 0.0f, 0.0f, 0.0f, RADIUS,

				-RADIUS, 0.0f, 0.0f, 0.0f, 0.0f, -RADIUS, 0.0f, -RADIUS, 0.0f

		});
		vertex.position(0);

		bb = ByteBuffer.allocateDirect(8 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);
		normal.put(new float[] { 0.577350269189f, 0.577350269189f,
				0.577350269189f, 0.577350269189f, 0.577350269189f,
				-0.577350269189f, 0.577350269189f, -0.577350269189f,
				0.577350269189f, 0.577350269189f, -0.577350269189f,
				-0.577350269189f, -0.577350269189f, 0.577350269189f,
				0.577350269189f, -0.577350269189f, 0.577350269189f,
				-0.577350269189f, -0.577350269189f, -0.577350269189f,
				0.577350269189f, -0.577350269189f, -0.577350269189f,
				-0.577350269189f });
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 24);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	/*
	 * Magic Numbers: r0 = ( 1, 0, 0 ) r1 = ( -1/3, 2 sqrt(2) / 3, 0 ) r2 = (
	 * -1/3, -sqrt(2) / 3, sqrt(6) / 3 ) r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3
	 * ) |r0| = |r1| = |r2| = |r3| = 1 Distance between any two points is 2
	 * sqrt(6) / 3
	 * 
	 * Normals: The unit normals are simply the negative of the coordinates of
	 * the point not on the surface.
	 */

	private static final int NUM_TETR_FACES = 4;

	private static float tet_r[][] = { { 1.0f, 0.0f, 0.0f },
			{ -0.333333333333f, 0.942809041582f, 0.0f },
			{ -0.333333333333f, -0.471404520791f, 0.816496580928f },
			{ -0.333333333333f, -0.471404520791f, -0.816496580928f } };

	private static int tet_i[][] = /* Vertex indices */
	{ { 1, 3, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 0, 1, 2 } };

	/*
	 * 四面体(线框)
	 */
	public static void glutWireTetrahedron(GL10 gl) {

		ByteBuffer bb = ByteBuffer.allocateDirect(4 * 3 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		vertex.put(tet_r[1]);
		vertex.put(tet_r[3]);
		vertex.put(tet_r[2]);

		vertex.put(tet_r[0]);
		vertex.put(tet_r[2]);
		vertex.put(tet_r[3]);

		vertex.put(tet_r[0]);
		vertex.put(tet_r[3]);
		vertex.put(tet_r[1]);

		vertex.put(tet_r[0]);
		vertex.put(tet_r[1]);
		vertex.put(tet_r[2]);

		vertex.position(0);

		bb = ByteBuffer.allocateDirect(4 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);
		normal.put(new float[] { -tet_r[0][0], -tet_r[0][1], -tet_r[0][2],
				-tet_r[1][0], -tet_r[1][1], -tet_r[1][2], -tet_r[2][0],
				-tet_r[2][1], -tet_r[2][2], -tet_r[3][0], -tet_r[3][1],
				-tet_r[3][2] });
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 12);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

	}

	/*
	 * 四面体
	 */
	public static void glutSolidTetrahedron(GL10 gl) {
		ByteBuffer bb = ByteBuffer.allocateDirect(4 * 3 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		vertex.put(tet_r[1]);
		vertex.put(tet_r[3]);
		vertex.put(tet_r[2]);

		vertex.put(tet_r[0]);
		vertex.put(tet_r[2]);
		vertex.put(tet_r[3]);

		vertex.put(tet_r[0]);
		vertex.put(tet_r[3]);
		vertex.put(tet_r[1]);

		vertex.put(tet_r[0]);
		vertex.put(tet_r[1]);
		vertex.put(tet_r[2]);

		vertex.position(0);

		bb = ByteBuffer.allocateDirect(4 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);
		normal.put(new float[] { -tet_r[0][0], -tet_r[0][1], -tet_r[0][2],
				-tet_r[1][0], -tet_r[1][1], -tet_r[1][2], -tet_r[2][0],
				-tet_r[2][1], -tet_r[2][2], -tet_r[3][0], -tet_r[3][1],
				-tet_r[3][2] });
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 12);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	private static float icos_r[][] = { { 1.0f, 0.0f, 0.0f },
			{ 0.447213595500f, 0.894427191000f, 0.0f },
			{ 0.447213595500f, 0.276393202252f, 0.850650808354f },
			{ 0.447213595500f, -0.723606797748f, 0.525731112119f },
			{ 0.447213595500f, -0.723606797748f, -0.525731112119f },
			{ 0.447213595500f, 0.276393202252f, -0.850650808354f },
			{ -0.447213595500f, -0.894427191000f, 0.0f },
			{ -0.447213595500f, -0.276393202252f, 0.850650808354f },
			{ -0.447213595500f, 0.723606797748f, 0.525731112119f },
			{ -0.447213595500f, 0.723606797748f, -0.525731112119f },
			{ -0.447213595500f, -0.276393202252f, -0.850650808354f },
			{ -1.0f, 0.0f, 0.0f } };

	private static int icos_v[][] = { { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 4 },
			{ 0, 4, 5 }, { 0, 5, 1 }, { 1, 8, 2 }, { 2, 7, 3 }, { 3, 6, 4 },
			{ 4, 10, 5 }, { 5, 9, 1 }, { 1, 9, 8 }, { 2, 8, 7 }, { 3, 7, 6 },
			{ 4, 6, 10 }, { 5, 10, 9 }, { 11, 9, 10 }, { 11, 8, 9 },
			{ 11, 7, 8 }, { 11, 6, 7 }, { 11, 10, 6 } };

	/*
	 * 二十面体(线框)
	 */
	public static void glutWireIcosahedron(GL10 gl) {
		ByteBuffer bb = ByteBuffer.allocateDirect(20 * 3 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		bb = ByteBuffer.allocateDirect(20 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);

		for (int i = 0; i < 20; i++) {
			normal.put((icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1])
					* (icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2])
					- (icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2])
					* (icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1]));
			normal.put((icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2])
					* (icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0])
					- (icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0])
					* (icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2]));
			normal.put((icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0])
					* (icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1])
					- (icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1])
					* (icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0]));

			vertex.put(icos_r[icos_v[i][0]]);
			vertex.put(icos_r[icos_v[i][1]]);
			vertex.put(icos_r[icos_v[i][2]]);
		}

		vertex.position(0);
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		for (int i = 0; i < 20; i++)
			gl.glDrawArrays(GL10.GL_LINE_LOOP, 3 * i, 3);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	/*
	 * 二十面体
	 */
	public static void glutSolidIcosahedron(GL10 gl) {
		ByteBuffer bb = ByteBuffer.allocateDirect(20 * 3 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		bb = ByteBuffer.allocateDirect(20 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);

		for (int i = 0; i < 20; i++) {
			normal.put((icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1])
					* (icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2])
					- (icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2])
					* (icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1]));
			normal.put((icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2])
					* (icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0])
					- (icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0])
					* (icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2]));
			normal.put((icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0])
					* (icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1])
					- (icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1])
					* (icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0]));

			vertex.put(icos_r[icos_v[i][0]]);
			vertex.put(icos_r[icos_v[i][1]]);
			vertex.put(icos_r[icos_v[i][2]]);
		}

		vertex.position(0);
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		for (int i = 0; i < 20; i++)
			gl.glDrawArrays(GL10.GL_TRIANGLES, 3 * i, 3);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	private static float rdod_r[][] = { { 0.0f, 0.0f, 1.0f },
			{ 0.707106781187f, 0.000000000000f, 0.5f },
			{ 0.000000000000f, 0.707106781187f, 0.5f },
			{ -0.707106781187f, 0.000000000000f, 0.5f },
			{ 0.000000000000f, -0.707106781187f, 0.5f },
			{ 0.707106781187f, 0.707106781187f, 0.0f },
			{ -0.707106781187f, 0.707106781187f, 0.0f },
			{ -0.707106781187f, -0.707106781187f, 0.0f },
			{ 0.707106781187f, -0.707106781187f, 0.0f },
			{ 0.707106781187f, 0.000000000000f, -0.5f },
			{ 0.000000000000f, 0.707106781187f, -0.5f },
			{ -0.707106781187f, 0.000000000000f, -0.5f },
			{ 0.000000000000f, -0.707106781187f, -0.5f }, { 0.0f, 0.0f, -1.0f } };

	private static int rdod_v[][] = { { 0, 1, 5, 2 }, { 0, 2, 6, 3 },
			{ 0, 3, 7, 4 }, { 0, 4, 8, 1 }, { 5, 10, 6, 2 }, { 6, 11, 7, 3 },
			{ 7, 12, 8, 4 }, { 8, 9, 5, 1 }, { 5, 9, 13, 10 },
			{ 6, 10, 13, 11 }, { 7, 11, 13, 12 }, { 8, 12, 13, 9 } };

	private static float rdod_n[][] = {
			{ 0.353553390594f, 0.353553390594f, 0.5f },
			{ -0.353553390594f, 0.353553390594f, 0.5f },
			{ -0.353553390594f, -0.353553390594f, 0.5f },
			{ 0.353553390594f, -0.353553390594f, 0.5f },
			{ 0.000000000000f, 1.000000000000f, 0.0f },
			{ -1.000000000000f, 0.000000000000f, 0.0f },
			{ 0.000000000000f, -1.000000000000f, 0.0f },
			{ 1.000000000000f, 0.000000000000f, 0.0f },
			{ 0.353553390594f, 0.353553390594f, -0.5f },
			{ -0.353553390594f, 0.353553390594f, -0.5f },
			{ -0.353553390594f, -0.353553390594f, -0.5f },
			{ 0.353553390594f, -0.353553390594f, -0.5f } };

	/*
	 * 菱形十二面体(线框)
	 */
	public static void glutWireRhombicDodecahedron(GL10 gl) {
		ByteBuffer bb = ByteBuffer.allocateDirect(12 * 4 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		bb = ByteBuffer.allocateDirect(12 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);

		for (int i = 0; i < 12; i++) {
			normal.put(rdod_n[i]);

			vertex.put(rdod_r[rdod_v[i][0]]);
			vertex.put(rdod_r[rdod_v[i][1]]);
			vertex.put(rdod_r[rdod_v[i][2]]);
			vertex.put(rdod_r[rdod_v[i][3]]);
		}

		vertex.position(0);
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		for (int i = 0; i < 12; i++)
			gl.glDrawArrays(GL10.GL_LINE_LOOP, 4 * i, 4);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	/*
	 * 菱形十二面体
	 */
	public static void glutSolidRhombicDodecahedron(GL10 gl) {
		ByteBuffer bb = ByteBuffer.allocateDirect(12 * 4 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer vertex = bb.asFloatBuffer();
		vertex.position(0);

		bb = ByteBuffer.allocateDirect(12 * 3 * 4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer normal = bb.asFloatBuffer();
		normal.position(0);

		for (int i = 0; i < 12; i++) {
			normal.put(rdod_n[i]);

			vertex.put(rdod_r[rdod_v[i][0]]);
			vertex.put(rdod_r[rdod_v[i][1]]);
			vertex.put(rdod_r[rdod_v[i][2]]);
			vertex.put(rdod_r[rdod_v[i][3]]);
		}

		vertex.position(0);
		normal.position(0);

		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glNormalPointer(GL10.GL_FLOAT, 0, normal);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
		for (int i = 0; i < 12; i++)
			gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 4 * i, 4);
		gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

}


使用的例子如下:

package fyj.engine.renderers;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLU;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import fyj.engine.utils.FreeGLUT;

public class FreeglutTestRenderer implements CommonRenderer {

	private float rot = 0;
	
	public FreeglutTestRenderer(Context ctx) {

	}
	
	@Override
	public void draw(GL10 gl) {
		// TODO Auto-generated method stub
		 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		 
		 gl.glMatrixMode(GL10.GL_MODELVIEW);
		 gl.glLoadIdentity();
		 
		 
		 gl.glTranslatef(0, 0, -0.2f);
		 gl.glRotatef(rot, 0, 1, 0);
		 rot += 0.5f;
//		 Log.i("37", " rot = " + rot);
		 
//		 Freeglut.glutSolidCube(gl, 1);
//		 Freeglut.glutWireSphere(gl, 1, 35, 45);
//		 FreeGLUT.glutWireTorus(gl, 0.5f, 1, 35, 30);
//		 Freeglut.glutSolidTorus(gl, 0.5f, 1, 20, 60);
		 
//		 FreeGLUT.glutWireDodecahedron(gl);
//		 FreeGLUT.glutSolidDodecahedron(gl);
		 
//		 FreeGLUT.glutWireOctahedron(gl);
//		 FreeGLUT.glutSolidOctahedron(gl);
		 
//		 FreeGLUT.glutWireTetrahedron(gl);
		 
//		 FreeGLUT.glutWireIcosahedron(gl);
//		 FreeGLUT.glutSolidIcosahedron(gl);
		 
//		 FreeGLUT.glutWireRhombicDodecahedron(gl);
//		 FreeGLUT.glutSolidRhombicDodecahedron(gl);

//		 FreeGLUT.glutWireCone(gl, 1.0f, 5.0f, 35, 30);
//		 FreeGLUT.glutSolidCone(gl, 1.0f, 5.0f, 35, 30);
		 
//		 FreeGLUT.glutWireCylinder(gl, 1.0f, 5, 35, 30);
		 FreeGLUT.glutSolidCylinder(gl, 1.0f, 5, 36, 30);
	}

	@Override
	public void resize(GL10 gl, int w, int h) {
		// TODO Auto-generated method stub
		float fAspect;

	    // Prevent a divide by zero, when window is too short
	    // (you cant make a window of zero width).
	    if(h == 0)
	        h = 1;

	    gl.glViewport(0, 0, w, h);
	        
	    fAspect = (float)w / (float)h;

	    // Reset the coordinate system before modifying
	    gl.glMatrixMode(GL10.GL_PROJECTION);
	    gl.glLoadIdentity();
		
	    // Set the clipping volume
	    GLU.gluPerspective(gl, 45.0f, fAspect, 1.0f, 50.0f);
	    GLU.gluLookAt(gl, 0, 0, -5, 0, 0, 0, 0, 1, 0);
	    gl.glMatrixMode(GL10.GL_MODELVIEW);
	    gl.glLoadIdentity();

	}

	@Override
	public void init(GL10 gl, EGLConfig config) {
		// TODO Auto-generated method stub
		gl.glClearColor(0.0f, 0.0f, .50f, 1.0f );
		
		gl.glEnable(GL10.GL_DEPTH_TEST); // Hidden surface removal

//		gl.glFrontFace(GL10.GL_CCW); // Counter clock-wise polygons face out
//
//		gl.glEnable(GL10.GL_CULL_FACE); // Do not calculate inside of jet		
		
	}

	@Override
	public boolean keyEvent(KeyEvent event) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void createMenu(Menu menu) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onMenuItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		
	}
}


 

你可能感兴趣的:(android,buffer,each,float,distance,Numbers)