android opengl 画球 画圆
16lz
2021-01-24
做了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);// 设置渲染模式}@Overridepublic 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 计算出变化的角度 可以让图形做简单的转动 改一改就可以平动了
不过球因为没有做处理 只是用单一颜色绘制的 所以看起来和圆差不多 可以加上颜色数组 就比较明显了
更多相关文章
- Android(安卓)文字倾斜
- Android中补间动画、属性动画效果演示
- Android(安卓)Scroll
- android中获取view的位置
- android自由改变Dialog窗口位置的方法
- Android(安卓)颜色渲染(六) RadialGradient 环形渲染
- Android(安卓)画布学习Canvas (1)坐标
- Android中实现物体在屏幕的移动
- Android滚动显示数字动画