做了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); <span style="color:#ff0000;">//------画圆</span>
- b.draw(gl); <span style="color:#ff0000;">//------画球</span>
- }
- 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 计算出变化的角度 可以让图形做简单的转动 改一改就可以平动了
不过球因为没有做处理 只是用单一颜色绘制的 所以看起来和圆差不多 可以加上颜色数组 就比较明显了