做了2个简单的类 一个是描述球的 一个是平面圆的
public class Ball
{
private int slices = 36; //越大越圆滑
private int stacks = 24; //同↑
private FloatBuffer[] normalsBuffers;
private FloatBuffer[] slicesBuffers;
private float yAngle;
private float zAngle;
float radius = 1.3f;
public Ball()
{
slicesBuffers = new FloatBuffer[slices];
normalsBuffers = new FloatBuffer[slices];
for (int i = 0; i < slices; i++) {
float[] vertexCoords = new float[6 * (stacks + 1)];
float[] normalCoords = new float[6 * (stacks + 1)];
double alpha0 = i * (2 * Math.PI) / slices;
double alpha1 = (i + 1) * (2 * Math.PI) / slices;
float cosAlpha0 = (float) Math.cos(alpha0);
float sinAlpha0 = (float) Math.sin(alpha0);
float cosAlpha1 = (float) Math.cos(alpha1);
float sinAlpha1 = (float) Math.sin(alpha1);
for (int j = 0; j <= stacks; j++)
{
double beta = j * Math.PI / stacks - Math.PI / 2;
float cosBeta = (float) Math.cos(beta);
float sinBeta = (float) Math.sin(beta);
setXYZ(vertexCoords, 6 * j,
radius * cosBeta * cosAlpha1,
radius * sinBeta,
radius * cosBeta * sinAlpha1);
setXYZ(vertexCoords, 6 * j + 3,
radius * cosBeta * cosAlpha0,
radius * sinBeta,
radius * cosBeta * sinAlpha0);
setXYZ(normalCoords, 6 * j,
cosBeta * cosAlpha1,
sinBeta,
cosBeta * sinAlpha1);
setXYZ(normalCoords, 6 * j + 3,
cosBeta * cosAlpha0,
sinBeta,
cosBeta * sinAlpha0);
}
slicesBuffers[i] = FloatBuffer.wrap(vertexCoords);
normalsBuffers[i] = FloatBuffer.wrap(normalCoords);
}
}
public void setXYZ(float[] vector, int offset, float x, float y, float z) {
vector[offset] = x;
vector[offset + 1] = y;
vector[offset + 2] = z;
}
public void draw(GL10 gl)
{
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -7.0f);
gl.glColor4f(1.0f, 0.2f, 0.3f, 1.0f);
gl.glRotatef(yAngle, 1.0f, 0.0f, 0.0f);
gl.glRotatef(zAngle, 0.0f, 1.0f, 0.0f);
for (int i = 0; i < slices; i++) {
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, slicesBuffers[i]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 2 * (stacks + 1));
}
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
}
public void setyAngle(float yAngle)
{
this.yAngle = yAngle;
}
public void setzAngle(float zAngle)
{
this.zAngle = zAngle;
}
}
public class Oval
{
private float[] vertices = new float[720];
private FloatBuffer verBuffer ;
private float yAngle;
private float zAngle;
public Oval()
{
//初始化圆形数据
for (int i = 0; i < 720; i += 2) {
// x 坐标
vertices[i] = (float) (Math.cos(DegToRad(i)) * 1);
// y 坐标
vertices[i+1] = (float) (Math.sin(DegToRad(i)) * 1);
}
//设置圆形顶点数据
ByteBuffer qbb = ByteBuffer.allocateDirect(vertices.length * 4);
qbb.order(ByteOrder.nativeOrder());
verBuffer = qbb.asFloatBuffer();
verBuffer.put(vertices);
verBuffer.position(0);
}
public float DegToRad(float deg)
{
return (float) (3.14159265358979323846 * deg / 180.0);
}
public void draw(GL10 gl)
{
//重置投影矩阵
gl.glLoadIdentity();
// 移动操作,移入屏幕(Z轴)5个像素, x, y , z
gl.glTranslatef(0.0f, 0.0f, -5.0f);
//旋转, angle, x, y , z
gl.glRotatef(yAngle, 0.0f, 1.0f, 0.0f);
gl.glRotatef(zAngle, 1.0f, 0.0f, 0.0f);
// 设置当前色为红色, R, G, B, Alpha
gl.glColor4f(1.0f, 0.1f, 0.1f, 1.0f);
//设置顶点类型为浮点坐标
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, verBuffer);
//打开顶点数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//向OGL发送实际画图指令
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 360);
//画图结束
gl.glFinish();
}
public void setyAngle(float yAngle)
{
this.yAngle = yAngle;
}
public void setzAngle(float zAngle)
{
this.zAngle = zAngle;
}
}
这个是renderer类 声明了Ball 和 Oval 变量
public class GLRender implements Renderer{
Oval o = new Oval();
Ball b = new Ball();
//度到弧度的转换
@Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glEnable(GL10.GL_CULL_FACE);
gl.glLightModelx(GL10.GL_LIGHT_MODEL_TWO_SIDE, GL10.GL_FALSE);
//o.draw(gl); //------画圆
b.draw(gl); //------画球
}
public void setyAngle(float yAngle)
{
b.setyAngle(yAngle);
o.setyAngle(yAngle);
}
public void setzAngle(float zAngle)
{
b.setzAngle(zAngle);
o.setzAngle(zAngle);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (height == 0) height = 1;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 1.0f, 100.0f);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0, 0, 0, 0);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glCullFace(GL10.GL_BACK);
gl.glEnable(GL10.GL_LIGHT0);
}
}
最后是GLSurfaceView类
public class MyGLSurfaceView extends GLSurfaceView
{
GLRender myRenderer;// 自定义的渲染器
private final float TOUCH_SCALE_FACTOR = 180.0f / 320;// 角度缩放比例
private float mPreviousY;// 上次的触控位置Y坐标
private float mPreviousX;// 上次的触控位置X坐标
float yAngle = 0;// 绕y轴旋转的角度
float zAngle = 0;// 绕z轴旋转的角度
public MyGLSurfaceView(Context context)
{
super(context);
myRenderer = new GLRender();// 创建渲染器
this.setRenderer(myRenderer);// 设置渲染器
this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);// 设置渲染模式
}
@Override
public boolean onTouchEvent(MotionEvent e)
{ // 触摸事件的回调方法
float x = e.getX();// 得到x坐标
float y = e.getY();// 得到y坐标
switch (e.getAction())
{
case MotionEvent.ACTION_MOVE:// 触控笔移动
float dy = y - mPreviousY;// 计算触控笔Y位移
float dx = x - mPreviousX;// 计算触控笔X位移
yAngle += dx * TOUCH_SCALE_FACTOR;// 设置沿y轴旋转角度
zAngle += dy * TOUCH_SCALE_FACTOR;// 设置沿z轴旋转角度
myRenderer.setyAngle(yAngle);
myRenderer.setzAngle(zAngle);
requestRender();// 重绘画面
}
mPreviousY = y;// 记录触控笔位置
mPreviousX = x;// 记录触控笔位置
return true;// 返回true
}
}
重写了ontouch 事件 通过x y 计算出变化的角度 可以让图形做简单的转动 改一改就可以平动了
不过球因为没有做处理 只是用单一颜色绘制的 所以看起来和圆差不多 可以加上颜色数组 就比较明显了